Files
swift-mirror/lib/Sema/CSSimplify.cpp
Jordan Rose eed34d15e7 Sema: Explicitly allow Optional-to-IUO when converting functions. (#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
2017-01-31 13:42:09 -08:00

166 KiB