We should pretty much always be reading
expression types out of the type cache in the constraint system.
We only see key path applications here on the path where we are
diagnosing a failure.
I haven't yet managed to come up with a test case that reproduces a crash
here.
Fixes: rdar://problem/41306933
We have a crash reported but do not have a test case and my attempt at
creating one was unsuccessful. It seems like the issue is that we have
an invalid decl that we attempt to access the interface type on,
though, so hopefully this fixes the issue.
I also tweaked the constraint generator to bail out when
checkObjCKeyPathExpr fails.
Potentially fixes: rdar://problem/40955755
8271c1a removed the last hacky usage of ArrayElementType,
leaving behind just the @lvalue-to-inout conversions. Rename
the locator path element to reflect this and do a bit of cleanup on the
unrelated-but-near-enough other hack RValueAdjustment.
Instead, generate the type variable in ConstraintGenerator.
However, we only want to generate it if we're type checking
from inside TypeChecker::typeCheckCompletionSequence(), so
add an isActivated() flag to CodeCompletionExpr. If it is
not set, constraint generation will simply fail on an
expression containing a CodeCompletionExpr.
Given something like `max(1, 2)` inside a type that conforms to Sequence, this
allows the compiler to consider Swift.max as well as the two methods with that
name on Sequence.
Many (perhaps most?) calls to createTypeVariable explicitly pass 0 for
options. This change just defaults the parameter to 0 and removes all
the explicit 0's in the code.
They can show up when re-typechecking via diag or code-completion and were
only being sanitized out in one place in CSDiag. Moved that logic into
SanitizeExpr.
Resolves rdar://problem/38149042
We were hitting an unreachable in visitDynamicMemberExpr in ExprRewriter when
re-typechecking during a salvage. Check for these earlier (in CSGen) and update
SanitizeExpr to handle them.
Resolves rdar://problem/39055736
We ended up supporting these coercions for Swift 3/4 via disjunctions,
so change our warning to one saying that it's deprecated rather than
erroneously telling the user that we're treating '!' as if it
were '?'.
Fixes rdar://problem/37121121.
If we're willing to tolerate less specific diagnostics, then we can
remove more instances of TVO_CanBindToInOut. After this change, there is
only one client of TVO_CanBindToInOut.
Rather than throw away the result of simplifying the expression if the
resulting is InOutType, see if the user explicitly created the
InOutType. If they did not, then the RValue type is fine.
This fixes two easy cases where we would go exponential in type
checking tuple literals.
Instead of generating a conversion to a single type variable (which
results in one large constraint system), we generate a conversion ot
the same type that appears in the initializer expression (which for
tuples is a tuple type, which naturally splits the constraint system).
I experimented with trying to generalize this further, but ran into
problems getting it working, so for now this will have to do.
Fixes rdar://problem/20233198.
Code completions calls typecheckUnresolvedExpression when completing unresolved members.
This calls an overload of solve() that bypasses sanitization, and without it we hit an
assertion failure in getTypeOfReference.
Resolves rdar://problem/38144409.
Improve support for Optional among other things.
Return Any when it is really the best answer given the types involved,
or nullptr if we cannot yet produce an accurate result.
This implementation returns Any? when joining Any with an
Optional<T>. In our type system both Any and Any? are effectively
subtypes of one another since each can hold all the values that the
other can hold. So this choice is somewhat arbitrary, but does line up
nicely with the notion that T is always a subtype of T?.
The code was favoring overloads where *either* argument matched its
parameter type and where both parameter types were the same. This
is really overly broad and can result in bugs like the one here, where
we only attempt the
(Int, Int) -> Bool
overload of '!=' despite the fact that it means forcing an
optional. We should select the
<T>(T?, T?) -> Bool
overload instead, and inject the non-optional operand into an optional.
Making this require *both* arguments to match mostly disables this
optimization, though, since for somethin like "a"+"b"+"c" the second
add has a type variable and string literal as arugments.
So instead, we'll just disable this in cases where one argument is the
optional of the other, to ensure we never try forcing one side. This
also means we'll disable the optimization in cases where we would
inject one operand into an optional, but that's likely find as we
don't have long chains of expressions where that happens.
Fixes rdar://problem/37073401.
This is useful for explicit casts and type expressions, where
type loc and expression types might be different, and allows
constraint solver to avoid setting opened types to expressions
which resolves multiple crashes.
When binding an optional value, or function that returns an optional
value, if that value was produced from a decl that was declared an
IUO, create a disjunction.
After solving, make use of the disjunction choices in rewriting
expressions to force optionals where needed.
This is disabled for now, as it results in a source compatibility
issue without associated changes that actually start generating
Optional<T> in place of ImplicitlyUnwrappedOptional<T>. It's
complicated, but basically having two '??' (one returning T, one
returning T?) and creating a disjunction where the first (favored)
choice is ImplicitlyUnwrappedOptional<T> and second is T results in
our selecting the wrong '??' in some cases.
Use this in places where we have a decl that is marked with the
ImplicitlyUnwrappedOptionalAttr so that we can distinguish in the
solver which decls need to be potentially unwrapped in order to type
check successfully.