Skip to content

[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

Merged

Conversation

hamishknight
Copy link
Contributor

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.

…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.
@slavapestov
Copy link
Contributor

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?

@slavapestov slavapestov self-assigned this Sep 11, 2018
@slavapestov
Copy link
Contributor

@swift-ci Please test

@slavapestov
Copy link
Contributor

@swift-ci Please test source compatibility

@hamishknight
Copy link
Contributor Author

@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?

@hamishknight
Copy link
Contributor Author

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.

@hamishknight hamishknight force-pushed the optional-to-archetype-swift5 branch from a2b30ae to 43dbdcc Compare September 12, 2018 13:18
@rudkx
Copy link
Contributor

rudkx commented Sep 15, 2018

@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.
@hamishknight
Copy link
Contributor Author

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.

@hamishknight
Copy link
Contributor Author

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.

@slavapestov
Copy link
Contributor

@swift-ci Please test

@slavapestov
Copy link
Contributor

@swift-ci Please test source compatibility

Copy link
Member

@DougGregor DougGregor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 2e2e8f0

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 2e2e8f0

@hamishknight
Copy link
Contributor Author

Oops, needed to update a test for the new mangling prefix. Compat suite passed (Release) (Debug).

@slavapestov
Copy link
Contributor

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 43cfc33

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 43cfc33

@slavapestov slavapestov merged commit dc8a0ac into swiftlang:master Sep 26, 2018
@hamishknight hamishknight deleted the optional-to-archetype-swift5 branch September 26, 2018 09:54
@hamishknight
Copy link
Contributor Author

Thanks Slava! Opened a 4.2 cherry-pick: #19562

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants