Skip to content

Sema: Explicitly allow Optional-to-IUO when converting functions #7168

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

jrose-apple
Copy link
Contributor

  • Explanation: A type checker rule preventing accidental Optional-to-ImplicitlyUnwrappedOptional conversions interacts poorly with deciding which function type conversions are allowed. This wouldn't be a problem except that an unrelated bug allowed a certain class of these conversions in Swift 3.0. Rather than try to emulate Swift 3.0's behavior, just allow Optional-to-IUO conversions when they appear as part of a function type conversion.
  • Scope: Only affects function type conversions that involve IUO.
  • Issue: SR-3758 / rdar://problem/30235814
  • Reviewed by: @DougGregor, @rudkx
  • Risk: Low, scope is very limited.
  • Testing: Added compiler regression tests.

@jrose-apple jrose-apple added this to the Swift 3.1 milestone Jan 31, 2017
@jrose-apple
Copy link
Contributor Author

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test OS X Platform
Git Commit - b1825954a6b424bebf5051bb903724c05c7c40a8
Test requested by - @jrose-apple

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test Linux Platform
Git Commit - b1825954a6b424bebf5051bb903724c05c7c40a8
Test requested by - @jrose-apple

…iftlang#7153)

We limit Optional-to-IUO as an implicit conversion to avoid making
common expressions ambiguous. However, this runs into trouble with
function-to-function conversions, which always look for a "Subtype"
relationship for their inputs and outputs. This is a conservative way
for Sema to avoid emitting conversions that SILGen cannot handle.

The problem case here is converting a closure with type '(Any!) ->
Void' to a value of type '(Any?) -> Void':

    let f: ((Any?) -> Void) = { (arg: Any!) in }

This is clearly a safe conversion, since 'Any!' and 'Any?' have the
same representation at run time, but historically we've disallowed it
because of the above rules. However, in Swift 3.0 this particular case
was permitted, with the type checker deciding that the 'Any?' argument
to 'f' could first itself be put into an 'Any', then /that/ value
could go through a value-to-optional conversion to make 'Any!'.
Fortunately the emitted code didn't follow this incorrect conversion
path.

This patch doesn't even try to emulate the old behavior. Instead, it
just weakens the restriction on Optional-to-IUO via a new type
matching flag that only applies within the context of matching
function types.

We can consider opening up function conversions in Swift 4 to anything
that supports conversion---not just subtyping---now that SILGen knows
how to automatically reabstract most such things. But whether we do or
not, Optional/IUO is a special case.

https://bugs.swift.org/browse/SR-3758
@jrose-apple
Copy link
Contributor Author

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test Linux Platform
Git Commit - b1825954a6b424bebf5051bb903724c05c7c40a8
Test requested by - @jrose-apple

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test OS X Platform
Git Commit - b1825954a6b424bebf5051bb903724c05c7c40a8
Test requested by - @jrose-apple

@tkremenek tkremenek merged commit 3e0c3b4 into swiftlang:swift-3.1-branch Jan 31, 2017
@jrose-apple jrose-apple deleted the 3.1-Optional-to-IUO branch January 31, 2017 23:47
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.

3 participants