This hooks up call argument position completion to the typeCheckForCodeCompletion API to generate completions from all the solutions the constraint solver produces (even those requiring fixes), rather than relying on a single solution being applied to the AST (if any).
Co-authored-by: Nathan Hawes <nathan.john.hawes@gmail.com>
`one-way` constraints disable some optimizations related to component
selection because they imply strict ordering. This is a problem for
multi-statement closures because variable declarations could involve
complex operator expressions that rely on aforementioned optimizations.
In order to fix that, let's move away from solving whole pattern binding
declaration into scheme that explodes such declarations into indvidual
elements and inlines them into a conjunction.
For example:
```
let x = 42, y = x + 1, z = (x, test())
```
Would result in a conjunction of three elements:
```
x = 42
y = x + 1
z = (x, test())
```
Each element is solved indepedently, which eliminates the need for
`one-way` constraints and re-enables component selection optimizations.
A local function can capture a variable that has been declared after it,
which means that type-checking such declaration in-order would trigger
sub-typecheck that would corrupt AST underness the solution application
walker.
Source compatibility workaround.
func test<T>(_: () -> T?) {
...
}
A multi-statement closure passed to `test` that has an optional
`Void` result type inferred from the body allows:
- empty `return`(s);
- to skip `return nil` or `return ()` at the end.
Implicit `return ()` has to be inserted as the last element
of the body if there is none. This wasn't needed before SE-0326
because result type was (incorrectly) inferred as `Void` due to
the body being skipped.
Resolves: rdar://85840941
It's possible that solution application either modifies or replaces the
`BraceStmt` that represents closure body, so we need to make sure that
body is always updated.
When a closure is provided with a contextual type that has isolated
parameters, infer that the corresponding closure parameter is "isolated".
Fixes rdar://83732479.
It's possible to declare explicit parameter/result type without
providing generic arguments, in such situation they'd be "opened"
as type variables and inferred from the contextual type or the body.
Type variable collector needs to account for that and include
such inner type variables into scope of an isolated closure.
Let `visitForEachPattern` handle both pattern and the sequence
expression associated with `for-in` loop because types in this
situation flow in both directions:
- From pattern to sequence, informing its element type e.g.
`for i: Int8 in 0 ..< 8`
- From sequence to pattern, when pattern has no type information.
In cases like:
```
func test<T>(_: () -> T?) -> [T] {
...
}
test {
if ... {
return
}
...
}
```
Contextual return type would be first attempted as optional and
then unwrapped if the first attempt did not succeed. To avoid having
to solve the closure twice (which results in an implicit function conversion),
let's add an implicit empty tuple (`()`) to the `return` statement
and allow it be to injected into optional as many times as context
requires.
If one or more outer closure parameters used in the body of an
inner closure have not been resolved when conjunction is created,
let's reference them in the conjunction constraint to avoid
disconnecting conjunction from its context.
Attempting to pre-compute a set of referenced type variables
upfront is incorrect because parameter(s) and/or result type
could be bound before conjunction is attempted. Let's compute
a set of referenced variables before each element gets attempted.
It is possible that contextual type of a parameter
has been assigned to an anonymous of named argument
early, to facilitate closure type checking. Such a
type can have type variables inside e.g.
```swift
func test<T>(_: (UnsafePointer<T>) -> Void) {}
test { ptr in
...
}
```
Type variable representing `ptr` in the body of
this closure would be bound to `UnsafePointer<$T>`
in this case, where `$T` is a type variable for a
generic parameter `T`.
Let's delay solution application to multi-statement closure bodies,
because declarations found in the body of such closures may depend
on its `ExtInfo` flags e.g. no-escape is set based on parameter if
closure is used in a call.
Bodies of multi-statement closures should be handled in isolation
because they don't dependent on anything expect parameter/result
types from outer context.