The constraint takes two pack types and makes sure that their
reduced shapes are equal. This helps with diagnostics because
constraint has access to the original pack expansion pattern
types.
If there are explicit generic arguments that fully resolves the
pack expansion, let's bind opened pack expansion to its contextual
type early (while resolving pack expansion variable), doing so
helps with performance and diagnostics.
If solver had to introduce an unlabeled single-element tuple around
contextual type, let's strip it and fix as a regular contextual mismatch
(instead of a tuple mismatch) because this action should be transparent
to diagnostics.
It's only safe to infer element type from `PackElementOf` constraint
when pattern type is fully resolved (because it can have pack element
archetypes which should be mapped out of context), the same applies
to the pattern type inference as well. Since constraints are re-activated
every time a referenced type variable is bound, simplication logic
can act as inference source by decaying into `Equal` constraints
where pattern/element type are resolved via surrounding information
first.
`openType` didn't need a locator before it was simply replacing generic
parameters with corresponding type variables but now, with opening of
pack expansions types, a locator is needed for pack expansion variables.
Pack expansion flattening could result in lose of tuple structure
or introduce a single element tuples (which are effectively parens),
to aid in matching `matchTypes` should introduce/maintain tuples on
both sides of the comparison until the structure is known.
This handles situations like `Int <conv> (Int, (_: $T_exp)` or
`String arg conv (_: $T_exp)`. The matching has to be delayed
because the structure of the tuple type is not known until `$T_exp`
(which represents a pack expansion type) is resolved.
Tuple types cannot be matched until all pack expansion variables
are resolved, the same is applicable to `shape of` constraints
because the structure of the pack is not fully resolved in such
cases.
Even if both sides are pack expansion variables they cannot be
merged because merging of them means merging of pattern and
shape types as well, which is easier to do when one of both
sides are bound.
A pack expansion type variable gets bound to its original pattern
type when solver can infer a contextual type for it. This makes
sure that pack expansion types are always matched via `matchTypes`
without `simplifyType` involvement which can expand them prematurely.
Diagnose base inference failure only if base gets inferred to be
a placeholder, any transitive placeholder inference points to the
problem being elsewhere.
Introduce `ConstraintSystem::recordTypeVariablesAsHoles` as a
standard way to record that unbound type variables found in a
type are holes in the given constraint system.
None of the restrictions like existential conversion or optional
promotion would actually match, so there is no point in trying them
just to add more unrelated fixes.
Resolves: rdar://100369066
When `matchTypesBindTypeVar` detects invalid pack reference it should
reset the type to a placeholder and allow binding to go through,
otherwise, if binding comes from inference, returning without binding
would create an infinite loop because type variable would perpetually
be the best choice to attempt.
If tuple doesn't have a label for its first element
and parameter does, let's assume parameter's label
to aid argument matching. For example:
```swift
func test(val: Int, _: String) {}
test(val: (42, "")) // expands into `(val: 42, "")`
```
Resolves: rdar://106775969
In Swift 5 and earlier initializer references are handled in a special
way that uses a type variable to represent a type of the parameter
list. Such type variables should be allowed to bind to a pack expansion
type to support cases where initializer has a single unlabeled variadic
generic parameter - `init(_ data: repeat each T)`.
If generic parameter comes from a variadic type declaration it's
possible that it got specialized early and is no longer represented
by a pack expansion type. For example, consider expression -
`Test<Int>(42)` where `Test<each T>` and the initializer
is declared as `init(_: repeat each T)`. Although declaration
based information reports parameter at index 0 as variadic generic
the call site specializes it to `Int`.
Resolves: rdar://107151854
Pack expansion types are handled by matching logic, optimization
that attempts to propagate types into the body of the closure should
consider them unsuitable even if the pack expansion matches a single
parameter.
This means two things:
- transformed closures behave just like regular multi-statement closures
- It's now possible to pass partially resolved parameter types into
the closure which helps with diagnostics.
Remove a bit of logic from `matchCallArgumentsImpl` that prevented
unlabeled argument matching after pack expansion argument until next
labeled argument because it incorrectly assumed that it represents
variadic forwarding.