swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.41k stars 10.34k forks source link

[SR-8956] New treatment of implicitly unwrapped optionals silently changes behavior of old code #51461

Open saagarjha opened 5 years ago

saagarjha commented 5 years ago
Previous ID SR-8956
Radar None
Original Reporter @saagarjha
Type Bug
Environment Xcode Version 10.1 beta 2 (10O35n)/macOS Mojave 10.14.1 Beta (18B57c)
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug | |Assignee | None | |Priority | Medium | md5: 06108f60b3f6ca40049f9b361ff8f20e

Issue Description:

I'm not quite sure this is a bug, but we had an issue with this in one of our apps that cropped up after we upgraded the version of Swift. Here's a quick code example that illustrates the problem:

func foo(_ any: Any?) {
    print("any")
}

func foo(_ int: Int) {
    print("int")
}

let bar: Int! = 0
foo(bar)

Prior to Swift 4.2 this would print "int" because the Swift would pick foo(_ int: Int) by unwrapping the IUO. However, this now prints "any" because bar decays into an optional–so it picks foo(_ any: Any?) instead. The actual code was using NSViewController.dismiss(_🙂, which has two overloads for a parameter of type Any? and NSViewController, but the underlying issue is the same. Is this a bug? If not, since this is a silent change in behavior, could we get a migration step would detect such usage and offer a warning with a fixit to unwrap the IUO or cast it to the method's type (i.e. foo(bar!) or foo(bar as Int))?

bc7072e8-7d37-4a38-8fee-cab463d443b7 commented 5 years ago

This is not a bug. Here is more information on the change that introduced the difference in behavior: https://swift.org/blog/iuo/

bc7072e8-7d37-4a38-8fee-cab463d443b7 commented 5 years ago

@rudkx, is it possible to provide migration step in this case? (The compiler does not support the old behavior, which would be one complication here.)