While synthesizing `~=` application for multi-statement closures or
result builder, solver shouldn't set types directly to newly
created AST nodes because they might not be fully resolved, instead
such types have to be recorded in the constraint system and then
set during solution application.
Resolves: rdar://91145060.
`typeEraseExistentialSelfReferences` shouldn't account for
contextual signature because that signature could have
generic parameters of it's own unrelated to the reference
which would be located before generic parameters of the
member, e.g. when the code is located in a protocol extension,
which invalidates the assumption that `Self` is located at
depth = 0, index = 0.
Resolves: rdar://91110069
Rather than looking solely at the existential argument of a generic
function to determine whether it self-conforms, compare the
existential argument against each of the protocols to which the
corresponding generic parameter conforms. This better models when the
existential value itself will successfully meet the requirements of
the generic function, and therefore not require opening.
This provides far better source compatibility by not changing
semantics of existing, well-formed calls, and eliminates the need to
special-case CoW-related operations in the standard library.
if there is a non-null callee.
Otherwise, getParameterList(callee) will crash if the callee is a closure.
Closures can't have default arguments anyway, so there's no need to
attempt this new inference.
Such existential arguments will already meet the requirements of a
generic function they are passed to, but would change runtime
semantics. Therefore, don't open the existential in such cases.
When we open an existential argument in a call to a generic function,
type-erase contravariant uses of that opened existential in subsequent
parameters. This primarily impacts closure parameters, where we want
the closure to be provided with an existential parameter type rather
than permit the parameter to have opened existential type. This
prevents the opened existential type from being directly exposed in
the type system.
Note that we do not need to perform this erasure when the argument is
a reference to a generic function, because there it is suitable to
infer that the generic arguments are the opened archetypes. This
subsumes the use case for `_openExistential`.
When solving for code completion, we weren't disabling overloads because the call might be malfored in the presence of a code completion token (because the user is only now writing the function call). But this logic doesn't apply to function calls that don't even involve the code completion token, which happens if completing in result builders.
I am hoping that this significantly improves code completion performance inside result builders.
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>
Represent this in much the same way that collections do by creating an opaque value representing the source argument, and a conversion expression representing the destination argument.
Add deep equality typing rules for
P =~= Q, T == X, U == Y, V == Z, ...
--------------------------------
P<T, U, V, ...> == Q<X, Y, Z, ...>
Also add existential matching rules to discharge the constraints on parameterized protocols against concrete types. e.g.
class C: P { typealias T = Int }
func foo<T>(_ x: P<T>) {}
foo(C())
Should cause T to unify against C.T = Int
This ensures that opened archetypes always inherit any outer generic parameters from the context in which they reside. This matters because class bounds may bind generic parameters from these outer contexts, and without the outer context you can wind up with ill-formed generic environments like
<τ_0_0, where τ_0_0 : C<T>, τ_0_0 : P>
Where T is otherwise unbound because there is no entry for it among the generic parameters of the environment's associated generic signature.
Augment the constraint solver to fallback to implicit `~=` application
when member couldn't be found for `EnumElement` patterns because
`case` statement should be able to match enum member directly, as well
as through an implicit `~=` operator application.