Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-6126] Unexpected casting result in Array/Optional. #48681

Closed
swift-ci opened this issue Oct 12, 2017 · 5 comments
Closed

[SR-6126] Unexpected casting result in Array/Optional. #48681

swift-ci opened this issue Oct 12, 2017 · 5 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-6126
Radar None
Original Reporter tarunon (JIRA User)
Type Bug
Status Resolved
Resolution Done
Environment

Xcode Version 9.0 (9A235)

Apple Swift version 4.0 (swiftlang-900.0.65 clang-900.0.37)

Target: x86_64-apple-macosx10.9

Additional Detail from JIRA
Votes 1
Component/s Compiler
Labels Bug
Assignee @tbkka
Priority Medium

md5: d7cc88bec6113716050efba120064739

duplicates:

  • SR-7358 Surprising inconsistency between optional conversion and array conversion

Issue Description:

I can check unexpected casting behavior combine Array and Optional.

func check(_ arg: Int??) -> String {
    switch arg {
    case .none: return ".none"
    case .some(.none): return ".some(.none)"
    case .some(.some): return ".some(.some)"
    }
}

let x: Int? = .none
let y: [Int?] = [.none]

let a = x as Int??
let b = (x as? Int??)!
let c = Int?.none as Int??
let d = (Int?.none as? Int??)!
let e = (y as [Int??]).first!
let f = (y as? [Int??])!.first!
let g = ([Int?.none] as [Int??]).first!
let h = ([Int?.none] as? [Int??])!.first!

// Every suspected results are .some(.none) but,

check(a) // .some(.none)
check(b) // .some(.none)
check(c) // .some(.none)
check(d) // .some(.none)
check(e) // .none
check(f) // .none
check(g) // .some(.none)
check(h) // .none

// Maybe its happen from this behavior

let z = String?.none as? Int? // .some(.none)
let zz = [String]() as? [Int] // []
let zzz = [String?.none] as? [Int?] // [nil]
@belkadan
Copy link
Contributor

cc @jckarter

@swift-ci
Copy link
Collaborator Author

swift-ci commented Mar 3, 2018

Comment by Nobuo Saito (JIRA)

I found problems obvious by Conditional Conformance.
In Swift4.1 (Xcode 9.3 b2), that happen.

let x = Int?.none
let y = Int??.none

x == y // false

let a = [x]
let b = [y]

a == b // true

@huonw
Copy link
Mannequin

huonw mannequin commented Apr 5, 2018

That last example is definitely a bit surprising, but I think it's the same problem that you've noticed in the main issue. The == operator is effectively behaving as an as cast for x and for a: it takes two arguments of the same type and so it needs to make sure both sides match (for the first one, both sides have type Int??, and for the second, both sides have type [Int??]).

Here's a different version of the same problem:

func sameType<T>(_ x: T, _ y: T) {
    print(x, y, T.self)
}

let x = Int?.none
let y = Int??.none
sameType(x, y)

let a: [Int?] = [x]
let b: [Int??] = [y]
sameType(a, b)

output:

Optional(nil) nil Optional<Optional<Int>>
[nil] [nil] Array<Optional<Optional<Int>>>

It seems like the [T?] to [T??] conversions are being implemented as

array.map { $0 { .some($0) } }
// instead of
array.map { .some($0) }

@tbkka
Copy link
Contributor

tbkka commented Aug 27, 2020

#33561 should fix this for the non-optimized case (where the cast is being handled by the runtime). There may still be issues with optimized casts, though.

@tbkka
Copy link
Contributor

tbkka commented Jan 5, 2021

I believe this is fully resolved now. Please let me know if you see any further issues in this area.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself
Projects
None yet
Development

No branches or pull requests

3 participants