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-9940] Dynamic casting in generic context broken for Swift 4.2 compatibility mode of Swift 5.0 #356

Closed
swift-ci opened this issue Feb 17, 2019 · 8 comments

Comments

@swift-ci
Copy link

@swift-ci swift-ci commented Feb 17, 2019

Previous ID SR-9940
Radar None
Original Reporter Polzin (JIRA User)
Type Bug
Status Closed
Resolution Won't Do
Environment

Swift Development Snapshot from 02-14-2019 or Swift 5.0 Snapshot from 02-15-2019

Xcode 10.2 beta 2 (10P91b)

Additional Detail from JIRA
Votes 0
Component/s Standard Library, XCTest
Labels Bug
Assignee None
Priority Medium

md5: 8b483ab6d51063e6890725659949b206

Issue Description:

I need some help figuring out exactly what I've stumbled upon here. I am getting different generic casting behavior depending on the environment and I am not sure what salient differences there are between the environments.

[EDIT] The below code exhibits the difference in behavior described depending on whether it is build with Swift version 4.2 or Swift version 5.0 (using the specified versions of the Swift 5.0 compiler/runtime.

Paste the snippet of code from the end of this description into an empty Mac OS Command line project's main.swift and build with language version 5.0 and you will get

test 1 type: "Optional<Int>"
true
test 2 type: "Optional<Int>"
true

Paste the same code into an XCTtest unit test function and running the test will produce Build the same code with Swift version 4.2 compatibility mode and you will get

test 1 type: "Optional<Int>"
true
test 2 type: "Optional<Int>"
false

Note you get true twice in the first output but true and false in the second output.

Here's the code

func testCast() -> Bool {
    print("test 1 type: \"\(Int?.self)\"")

    guard let _ = Any?.none as? Int? else {
        return false
    }

    return true
}

func testGenericCast<T>(_ type: T.Type) -> Bool {
    print("test 2 type: \"\(T.self)\"")

    guard let _ = Any?.none as? T else {
        return false
    }

    return true
}

print(testCast())
print(testGenericCast(Int?.self))

Things I have tried that do not make a difference in the results pasted above:
1. Embed the code in a function within main.swift.
2. Embed the code in a static function on a struct within main.swift.
3. Embed the code in a function on a class within main.swift.

A third environment in which the generic cast fails (same result as when run within a XCTest unit test):
The body of func application(_:, didFinishLaunchingWithOptions: ) in an empty iOS app.

@swift-ci
Copy link
Author

@swift-ci swift-ci commented Feb 17, 2019

Comment by Mathew Polzin (JIRA)

@hamishknight any ideas spring to mind here? You helped me identify a very similar problem with generic casting (SR-9837), but this is definitely a distinct bug.

@hamishknight
Copy link

@hamishknight hamishknight commented Feb 17, 2019

This certainly sounds like SR-9837, though I'm unable to reproduce it in Xcode 10.2 beta 2 using the 2019-02-14 master snapshot (I tested the code in both an iOS project and in an XCTest unit test).

@swift-ci
Copy link
Author

@swift-ci swift-ci commented Feb 17, 2019

Comment by Mathew Polzin (JIRA)

I'll be darned. When you were unable to reproduce I took a closer look at the build targets and figured it out. My Command Line executable target specified Swift 5.0 but the unit test target and the iOS target both specified Swift 4.2 (an unintuitive default in this case given that I was creating the new targets within the same project where the command line executable target had been created with a default language version of Swift 5.0).

I did a bit more testing and was able to confirm outside of Xcode (using only `swiftc` and `SwiftPM`) that a the difference is whether the target is built with language version 5.0 or 4.2. In other words, this is a regression in Swift 4.2 compatibility of Swift 5.0, right?

@hamishknight
Copy link

@hamishknight hamishknight commented Feb 17, 2019

Ah okay right – the change in behaviour you're seeing here by using Swift 4(.2) mode as opposed to Swift 5 mode is the change called out the release notes. What happened was I originally merged a fix for Swift 4.2, however that caused a compatibility regression (SR-8704) due to the fact that it wasn't guarded by compatibility mode. So now that fix is guarded by Swift 5 compatibility mode. Therefore by running in Swift 4 or 4.2 compatibility mode, you get the behaviour you would have gotten in Swift 4 (i.e without the original fix that regressed compatibility).

So long story short, this is working as expected. It's certainly unfortunate that the behaviour has flip-flopped between versions though :/

@swift-ci
Copy link
Author

@swift-ci swift-ci commented Feb 17, 2019

Comment by Mathew Polzin (JIRA)

OK. Thanks for the explanation. If I understand correctly, I will close this issue.

What I am hearing is (given that I have some code hitting this regression right now): My code will just always have to be built with the Swift 4.2 compiler in Swift 4.2 mode or the Swift 5.0 compiler in Swift 5.0 mode; there is no middle ground for someone wanting to continue building it as a Swift 4.2 target once upgrading to the Swift 5.0 compiler.

Although unfortunate, I accept that and it does not seem like the end of the world to me.

@hamishknight
Copy link

@hamishknight hamishknight commented Feb 17, 2019

Yes, that is unfortunately correct in your case. In hindsight, it would have perhaps been better to also allow the fix in Swift 4.2 compatibility mode as well as Swift 5 mode.

@swift-ci
Copy link
Author

@swift-ci swift-ci commented Feb 17, 2019

Comment by Mathew Polzin (JIRA)

Thank you very much for the explanation. I imagine for the most part adoption of version 5 by the community will be... "swift" 😉 so hopefully not too many people will be left begrudgingly updating their source code.

@swift-ci
Copy link
Author

@swift-ci swift-ci commented Feb 17, 2019

Comment by Mathew Polzin (JIRA)

Closing as won't do because, although I think we have identified a potential way to make Swift 4.2 compatibility mode work, I don't see that happening for version 5.0 this late in the game and I am satisfied with understanding the cause of the behavior so I can explain it to anyone that asks me about it.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@shahmishal shahmishal transferred this issue from apple/swift May 9, 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

2 participants