-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Sema] Restrict new optional-to-archetype casting behaviour to Swift 5 mode #19217
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
[Sema] Restrict new optional-to-archetype casting behaviour to Swift 5 mode #19217
Conversation
…5 mode In swiftlang#13910, the behaviour of optional-to-archetype casts changed such that we're now more conservative with the unwrapping of the operand at compile time in order to account for the fact that an optional type could be substituted at runtime. This brought such casting behaviour inline with that in a non-generic context, however it wasn't properly gated by Swift version, leading to compatibility issues. This commit restricts the new behaviour to Swift 5 mode and above. Resolves SR-8704.
Hey @hamishknight, can you add entries to CHANGELOG.md for the various Swift 5-specific changes you've made, such as this fix and the redeclaration checking change? |
@swift-ci Please test |
@swift-ci Please test source compatibility |
@slavapestov I've added changelog entries for this and the redeclaration change (happy to split the latter off into a separate PR if you feel it would be better reviewed separately). I wasn't sure whether to add an entry for #18951 as it feels more like a bug fix for the existing "favour members on concrete types over protocol members" rule – even though it is technically source breaking for a small number of quite contrived cases. Thoughts? |
Debug compat suite failure appears to be unrelated – Chatto is failing quite consistently, and ProcedureKit is failing intermittently (e.g also in https://ci.swift.org/job/swift-PR-source-compat-suite-debug/72/). Release compat suite passed. |
a2b30ae
to
43dbdcc
Compare
@swift-ci please smoke test |
The result of such a cast doesn't always match that in a non-generic context when the type being cast to is more optional than the value, as the compiler can perform eager optional injection. For example: ```swift func forceCast<T>(_ value: Any?, to type: T.Type) -> T { return value as! T } let value: Any? = Any??.none print(value as! Any??) // Optional(nil) print(forceCast(value, to: Any??.self)) // nil ``` Therefore change the wording to indicate that the behaviour now more closely matches the result you would get in a non-generic context.
Just realised that the new behaviour doesn't entirely follow the rule of matching the behaviour in a non-generic context, as the compiler can perform eager optional injection if it knows you're casting to a more optional type (which was the case even before #13910). For example: func forceCast<T>(_ value: Any?, to type: T.Type) -> T {
return value as! T
}
let value: Any? = Any??.none
print(value as! Any??) // Optional(nil)
print(forceCast(value, to: Any??.self)) // nil I've therefore edited the wording in the changelog to more accurately reflect this. |
Just resolved a merge conflict in the changelog – is this good to go? If possible, I'd like to open a 4.2 cherry-pick for a potential 4.2.1 release to minimise compatibility issues. |
@swift-ci Please test |
@swift-ci Please test source compatibility |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Build failed |
Build failed |
@swift-ci Please test |
Build failed |
Build failed |
Thanks Slava! Opened a 4.2 cherry-pick: #19562 |
In #13910, the behaviour of optional-to-archetype casts changed such that we're now more conservative with the unwrapping of the operand at compile time in order to account for the fact that an optional type could be substituted at runtime. This brought such casting behaviour inline with that in a non-generic context, however it wasn't properly gated by Swift version, leading to compatibility issues.
This PR restricts the new behaviour to Swift 5 mode and above.
Resolves SR-8704.