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-4248] Runtime exception casting an Any? nil to a generic optional #46831

Closed
swift-ci opened this issue Mar 15, 2017 · 5 comments
Closed

[SR-4248] Runtime exception casting an Any? nil to a generic optional #46831

swift-ci opened this issue Mar 15, 2017 · 5 comments

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Mar 15, 2017

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

Apple Swift version 3.0.2 (swiftlang-800.0.63 clang-800.0.42.1)
Target: x86_64-apple-macosx10.9

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, RunTimeCrash, Runtime
Assignee @hamishknight
Priority Medium

md5: adedc48208df41d3ff061c642c889341

is duplicated by:

  • SR-14356 Casting from generic placeholder type T to Any? fails, when T resolves to Any?, when build with -swift-version 4.2

relates to:

  • SR-8704 Cast from Any? to as? Value where Value == Any produces unexpected result in Xcode 10

Issue Description:

Summary

An unexpected fatal error in a forced downcast from a nil to an optional generic type T, e.g. T = String?.

  • NOTE: Casting nil as Any before the forced downcast is a workaround to avoid the runtime fatal error. Perhaps this in itself is its own bug?

  • NOTE: This is similar to a previously reported and resolved bug: https://bugs.swift.org/browse/SR-912 — in this case, the input type is Any and not Any?.

Code Example

struct Cast<T> {
  // Crashes if `value` is `nil`
  func optional(_ value: Any?) {
    output(value as! T)
  }

  // Should be identical to `optional`, but it's not. Perhaps a separate bug here?
  func workaround(_ value: Any?) {
    output((value as Any) as! T)
  }

  private func output(_ value: T) {
    print(value as Any)
  }
}

let cast = Cast<String?>()

let full: String? = "Hello"
cast.optional(full as Any)   // Optional("Hello")
cast.workaround(full as Any) // Optional("Hello")

let empty: String? = nil
cast.workaround(empty)      // nil
cast.optional(empty)        // FATAL ERROR: unexpectedly found nil while unwrapping an Optional value
@belkadan
Copy link
Contributor

belkadan commented Mar 15, 2017

cc @jckarter

@hamishknight
Copy link
Collaborator

hamishknight commented Jan 12, 2018

#13910

@norio-nomura
Copy link
Contributor

norio-nomura commented Mar 8, 2019

This issue is described in the release note of Swift 5. But was this already changed in 4.2?
https://developer.apple.com/documentation/xcode_release_notes/xcode_10_2_beta_4_release_notes/swift_5_release_notes_for_xcode_10_2_beta_4

In Swift 5 mode, when casting an optional value to a generic placeholder type, the compiler will be more conservative with the unwrapping of the value. The result of such a cast now more closely matches the result you would get in a nongeneric context. (SR-4248) (47326318)

@hamishknight
Copy link
Collaborator

hamishknight commented Mar 8, 2019

@norio-nomura That is correct – the change was initially made to Swift 4.2, however that accidentally caused a compatibility regression ([SR-8704]) so in Swift 5 the behaviour was limited to Swift 5 mode (with Swift 4.x modes using the old behaviour), which is the change described by the changelog.

@norio-nomura
Copy link
Contributor

norio-nomura commented Mar 8, 2019

@hamishknight Thanks for answer.
Hm, the release note seems a little unclear description.
Until I received your answer here, I did not understand that the behavior of Swift 5 with -swift-version 4.2 is not compatible with Swift 4.2.x.

@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
Projects
None yet
Development

No branches or pull requests

4 participants