This fallback to `typeCheckExpression` is triggered when it's
determined that code completion expression is located inside
of a multi-statement closure and its body is going going to
participate in type-check.
Using `SolutionApplicationTarget` make it easier to propage
contextual information and avoid mistakes of using incorrect
accessors for constraint generation.
If an expression fails pre-check or constraint generation,
code completion should be performed directly on the
`CodeCompletionExpr` as a fallback. Let's factor that logic
out from `solveForCodeCompletion` and put it directly into
`typeCheckForCodeCompletion` because it's easier to establish
fault conditions there.
To aid code completion, we need to attempt to convert type holes
back into underlying generic parameters if possible, since type
of the code completion expression is used as "expected" (or contextual)
type so it's helpful to know what requirements it has to filter
the list of possible member candidates e.g.
```swift
func test<T: P>(_: [T]) {}
test(42.#^MEMBERS^#)
```
It's impossible to resolve `T` in this case but code completion
expression should still have a type of `[T]` instead of `[<<hole>>]`
because it helps to produce correct contextual member list based on
a conformance requirement associated with generic parameter `T`.
If there was an invalid reference which was caught by pre-check,
let's remove all context besides code completion itself and use
it to produce code completion results.
Add a flag to `ConstraintSystem::preCheckExpression` and subsequently
to `TypeChecker::resolveDeclRefExpr` to indicate whether it's allowed
to replace invalid member refs with `ErrorExpr`.
It is useful for diagnostics and code completion to preserve AST
in it's original state otherwise it's impossible to diagnose errors
post factum or extract `CodeCompletionExpr` when it's a child of an
invalid reference.
To better preserve source compatibility, teach the constraint
solver to try both the new forward scanning rule as well as the
backward scanning rule when matching a single, unlabeled trailing
closure. In the extreme case, where the unlabeled trailing closure
matches different parameters with the different rules, and yet both
produce a potential match, introduce a disjunction to explore both
possibilities.
Prefer solutions that involve forward scans to those that involve
backward scans, so we only use the backward scan as a fallback.
Since bindings now require finalization we need a new endpoint
which perform all of the required actions before returning complete
`PotentialBindings` object when they are requested for a particular
type variable without any other context.
TapExpr has a 'VarDecl' the type of which is determined by type checking
the parent interpolated string literal expression. Type checking TapExpr
elements before that always fails, thus a waste of the computing time.
As part of the code completion redesign this new entry point is going
to replace use of:
- `typeCheckExpression`
- `getTypeOfExpressionWithoutApplying` (which could be removed)
and possibly other methods currently used to retrieve information
for code completion purposes.
Advantages of a new approach:
- Avoids mutating AST;
- Allows to avoid sub-expression type-checking;
- Allows code completion access to multiple solutions in ambiguous cases;
- Provides all possible solutions - valid and invalid (with holes);
- Allows code completion to easily access not only types but
overload choices and other supplimentary information associated
with each solution.
Introduce an experimental mode (behind the flag
`experimental-one-way-closure-params`) that places one-way
constraints between closure parameter types and references to those
parameters within the body of the closure. The intent here is to
break up constraint systems further, potentially improving type
checking performance and making way for larger closure bodies to be
supported.
This is a source-breaking change when the body of a single-expression
closure is used to determine the parameter types. One obvious example
is when there is no contextual type, e.g.,
let _ = { $0 + 1 }
this type-checks today because `1` becomes `Int`, which matches the
`+` overload with the type `(Int, Int) -> Int`, determining the
parameter type `Int` for the closure. Such code would not type-check
with one-way constraints.
Now that these are stored in the TypeResolution object itself, and all callers that mutate flags create a new resolution object, this data can be derived from the resolution itself.
Add the appropriate assertions to ensure that the now-redundant options parameters are being kept in sync so they can be retracted.
The eventual goal is to have TypeResolution requestified.
All callers can trivially be refactored to use ModuleDecl::lookupConformance()
instead. Since this was the last flag in ConformanceCheckOptions, we can remove
that, too.