Also stop suggesting a '?' fix-it for casts, where it is not likely to
be helpful because the common intention is either to force the optional
or declare an IUO.
This was previously an artificial limitation of the
FunctionRefKind representation, there's no reason
we shouldn't support IUOs for functions referenced
using a compound name.
The current IUO design always forms a disjunction
at the overload reference, for both:
- An IUO property `T!`, forming `$T := T? or T`
- An IUO-returning function `() -> T!`, forming `$T := () -> T? or () -> T`
This is simple in concept, however it's suboptimal
for the latter case of IUO-returning functions for
a couple of reasons:
- The arguments cannot be matched independently of
the disjunction
- There's some awkwardness when it comes e.g wrapping
the overload type in an outer layer of optionality
such as `(() -> T!)?`:
- The binding logic has to "adjust" the correct
reference type after forming the disjunction.
- The applicable fn solving logic needs a special
case to handle such functions.
- The CSApply logic needs various hacks such as
ImplicitlyUnwrappedFunctionConversionExpr to
make up for the fact that there's no function
conversion for IUO functions, we can only force
unwrap the function result.
- This lead to various crashes in cases where
we we'd fail to detect the expr and peephole
the force unwrap.
- This also lead to crashes where the solver
would have a different view of the world than
CSApply, as the former would consider an
unwrapped IUO function to be of type `() -> T`
whereas CSApply would correctly see the overload
as being of type `() -> T?`.
To remedy these issues, IUO-returning functions no
longer have their disjunction formed at the overload
reference. Instead, a disjunction is formed when
matching result types for the applicable fn
constraint, using the callee locator to determine
if there's an IUO return to consider. CSApply then
consults the callee locator when finishing up
applies, and inserts the force unwraps as needed,
eliminating ImplicitlyUnwrappedFunctionConversionExpr.
This means that now all IUO disjunctions are of the
form `$T := T? or T`. This will hopefully allow a
further refactoring away from using disjunctions
and instead using type variable binding logic to
apply the correct unwrapping.
Fixes SR-10492.
If we encounter a placeholder type here, propagate
it to the type variable, as we don't know whether
it should be optional or non-optional, and we
would have already recorded a fix for it.
SR-15219
rdar://83352038
Make sure that we're resolving types and patterns using the
PatternBindingDecl context, both for the type resolver context and the
contextual pattern used for pattern resolution.
Fixes a regression with implicitly-unwrapped options reported as
SR-11998 / rdar://problem/58455441.
When we determine that an optional value needs to be unwrapped to make
an expression type check, use notes to provide several different
Fix-It options (with descriptions) rather than always pushing users
toward '!'. Specifically, the errors + Fix-Its now looks like this:
error: value of optional type 'X?' must be unwrapped to a value of
type 'X'
f(x)
^
note: coalesce using '??' to provide a default when the optional
value contains 'nil'
f(x)
^
?? <#default value#>
note: force-unwrap using '!' to abort execution if the optional
value contains 'nil'
f(x)
^
!
Fixes rdar://problem/42081852.
This disappeared in the rework of IUOs but is needed when we have
multiple potential solutions involving different sets of overloads or
type bindings.
Fixes rdar://problem/37475971.
We just needed to select the final type based on which branch of the
disjunction successfully type-checked the expression.
Fixes [SR-7208](https://bugs.swift.org/browse/SR-7208)
and rdar://problem/37159360.
We were inserting function conversion expressions that were then
turned into forces of values in cases where we merely referenced
functions, but did not actually call them.
Fixes rdar://problem/37241550.
Also remove the decl from the known decls and remove a
bunch of code referencing that decl as well as a bunch of other
random things including deserialization support.
This includes removing some specialized diagnostics code that
matched the identifier ImplicitlyUnwrappedOptional, and tweaking
diagnostics for various modes and various issues.
Fixes most of rdar://problem/37121121, among other things.
Stop creating ImplicitlyUnwrappedOptional<T> so that we can remove it
from the type system.
Enable the code that generates disjunctions for Optional<T> and
rewrites expressions based on the original declared type being 'T!'.
Most of the changes supporting this were previously merged to master,
but some things were difficult to merge to master without actually
removing IUOs from the type system:
- Dynamic member lookup and dynamic subscripting
- Changes to ensure the bridging peephole still works
Past commits have attempted to retain as much fidelity with how we
were printing things as possible. There are some cases where we still
are not printing things the same way:
- In diagnostics we will print '?' rather than '!'
- Some SourceKit and Code Completion output where we print a Type
rather than Decl.
Things like module printing via swift-ide-test attempt to print '!'
any place that we now have Optional types that were declared as IUOs.
There are some diagnostics regressions related to the fact that we can
no longer "look through" IUOs. For the same reason some output and
functionality changes in Code Completion. I have an idea of how we can
restore these, and have opened a bug to investigate doing so.
There are some small source compatibility breaks that result from
this change:
- Results of dynamic lookup that are themselves declared IUO can in
rare circumstances be inferred differently. This shows up in
test/ClangImporter/objc_parse.swift, where we have
var optStr = obj.nsstringProperty
Rather than inferring optStr to be 'String!?', we now infer this to
be 'String??', which is in line with the expectations of SE-0054.
The fact that we were only inferring the outermost IUO to be an
Optional in Swift 4 was a result of the incomplete implementation of
SE-0054 as opposed to a particular design. This should rarely cause
problems since in the common-case of actually using the property rather
than just assigning it to a value with inferred type, we will behave
the same way.
- Overloading functions with inout parameters strictly by a difference
in optionality (i.e. Optional<T> vs. ImplicitlyUnwrappedOptional<T>)
will result in an error rather than the diagnostic that was added
in Swift 4.1.
- Any place where '!' was being used where it wasn't supposed to be
allowed by SE-0054 will now treat the '!' as if it were '?'.
Swift 4.1 generates warnings for these saying that putting '!'
in that location is deprecated. These locations include for example
typealiases or any place where '!' is nested in another type like
`Int!?` or `[Int!]`.
This commit effectively means ImplicitlyUnwrappedOptional<T> is no
longer part of the type system, although I haven't actually removed
all of the code dealing with it yet.
ImplicitlyUnwrappedOptional<T> is is dead, long live implicitly
unwrapped Optional<T>!
Resolves rdar://problem/33272674.
Allow passing Optional<T> as inout where
ImplicitlyUnwrappedOptional<T> is expected, and vice-versa.
Swift 4.1 added a warning that overloading inouts by kind of optional
was deprecated and would be removed, but we didn't actually allow
people to remove an overload and pass arguments of the other kind of
optional to the remaining function.
Fixes rdar://problem/36913150
This is a nice contained test case that has the goal of testing all
the new functionality. Having this committed before the code changes
will make it clear whether any behavior changes between the old and
new implementation (I expect some small diagnostic changes like
uttering T? instead of T! for some types).