Instead of failing constraint generation by returning `nullptr` for an `ErrorExpr` or returning a null type when a type fails to be resolved, return a fresh type variable. This allows the constraint solver to continue further and produce more meaningful diagnostics.
Most importantly, it allows us to produce a solution where previously constraint generation for a syntactic element had failed, which is required to type check multi-statement closures in result builders inside the constraint system.
Type inside of an editor placeholder is more of a hint than anything else,
so if it's incorrect let's diagnose that and use type variable instead to
allow solver to make forward progress.
Resolves: SR-14213
Resolves: rdar://74356736
If constraint system is underconstrained e.g. because there are
editor placeholders, it's possible to end up with multiple solutions
where each ambiguous declaration is going to have its own overload kind:
```swift
func foo(_: Int) -> [Int] { ... }
func foo(_: Double) -> (result: String, count: Int) { ... }
_ = foo(<#arg#>).count
```
In this case solver would produce 2 solutions: one where `count`
is a property reference on `[Int]` and another one is tuple access
for a `count:` element.
Resolves: rdar://problem/49712598
Patch up all the places that are making a syntactic judgement about the
isInvalid() bit in a ValueDecl. They may continue to use that query,
but most guard themselves on whether the interface type has been set.
This is an amalgam of simplifications to the way VarDecls are checked
and assigned interface types.
First, remove TypeCheckPattern's ability to assign the interface and
contextual types for a given var decl. Instead, replace it with the
notion of a "naming pattern". This is the pattern that semantically
binds a given VarDecl into scope, and whose type will be used to compute
the interface type. Note that not all VarDecls have a naming pattern
because they may not be canonical.
Second, remove VarDecl's separate contextual type member, and force the
contextual type to be computed the way it always was: by mapping the
interface type into the parent decl context.
Third, introduce a catch-all diagnostic to properly handle the change in
the way that circularity checking occurs. This is also motivated by
TypeCheckPattern not being principled about which parts of the AST it
chooses to invalidate, especially the parent pattern and naming patterns
for a given VarDecl. Once VarDecls are invalidated along with their
parent patterns, a large amount of this diagnostic churn can disappear.
Unfortunately, if this isn't here, we will fail to catch a number of
obviously circular cases and fail to emit a diagnostic.
along with recent policy changes:
- For expression types that are not specifically handled, make sure to
produce a general "unused value" warning, catching a bunch of unused
values in the testsuite.
- For unused operator results, diagnose them as uses of the operator
instead of "calls".
- For calls, mutter the type of the result for greater specificity.
- For initializers, mutter the type of the initialized value.
- Look through OpenExistentialExpr's so we can handle protocol member
references propertly.
- Look through several other expressions so we handle @discardableResult
better.
mode (take 2)
Allow untyped placeholder to take arbitrary type, but default to Void.
Add _undefined<T>() function, which is like fatalError() but has
arbitrary return type. In playground mode, merely warn about outstanding
placeholders instead of erroring out, and transform placeholders into
calls to _undefined(). This way, code with outstanding placeholders will
only crash when it attempts to evaluate such placeholders.
When generating constraints for an iterated sequence of type T, emit
T convertible to $T1
$T1 conforms to SequenceType
instead of
T convertible to SequenceType
This ensures that an untyped placeholder in for-each sequence position
doesn't get inferred to have type SequenceType. (The conversion is still
necessary because the sequence may have IUO type.) The new constraint
system precipitates changes in CSSimplify and CSDiag, and ends up fixing
18741539 along the way.
(NOTE: There is a small regression in diagnosis of issues like the
following:
class C {}
class D: C {}
func f(a: [C]!) { for _: D in a {} }
It complains that [C]! doesn't conform to SequenceType when it should be
complaining that C is not convertible to D.)
<rdar://problem/21167372>
(Originally Swift SVN r31481)
Allow untyped placeholder to take arbitrary type, but default to Void.
Add _undefined<T>() function, which is like fatalError() but has
arbitrary return type. In playground mode, merely warn about outstanding
placeholders instead of erroring out, and transform placeholders into
calls to _undefined(). This way, code with outstanding placeholders will
only crash when it attempts to evaluate such placeholders.
<rdar://problem/21167372> transform EditorPlaceholderExpr into fatalError()
Swift SVN r31481
where we type check the destination first, then apply its type to the source.
This allows us to get diagnostics for assignments that are as good as PBD
initializers and other cases.
Swift SVN r31404
- Fix TypeCheckExpr.cpp to be more careful when propagating sugar from an
argument to the result of the function. We don't want to propagate parens,
because they show up in diagnostics later.
- Restructure FailureDiagnosis::diagnoseFailure() to strictly process the tree
in depth first order. Before it would only do this if contextual typing was
unavailable, leading to unpredictable inconsistencies between diagnostics.
- Always perform diagnoseContextualConversionError early, as part of the thing
that calls the visitor, instead of in each visit method. This may change in
the future, but is a simplification for now.
- Make the operator processing code handle the "candidate is an exact match"
case by emitting a diagnostic indicating that the result type of the operator
must not match expectations, instead of emitting the silly things like
"binary operator '&' cannot be applied to two Int operands" which is obviously
false.
These changes lead to minor improvements across the testsuite, and should make the
diagnostics more predictable for more complex real-world ones, but I haven't gone
through the radars yet.
Major missing pieces:
- CallExpr isn't using the same logic that the operators are.
- When you have a near match (only one argument mismatches) we should specifically
complain about that argument, instead of spewing an entire argument list.
- The noescape function attr diagnostic is being emitted twice now.
Swift SVN r29733
If the placeholder is a typed one, parse its type string into a TypeRepr,
resolve it during typechecking and set it as the type for the associated EditorPlaceholderExpr.
Swift SVN r26215