Skip to content

[ConstraintSystem] Model pack expansion types via type variables #65125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 36 commits into from
May 2, 2023

Conversation

xedin
Copy link
Contributor

@xedin xedin commented Apr 12, 2023

  • Adds TVO_PackExpansion to denote that a type variable can only be bound to a pack expansion type;
  • Adjusts openType and openUnboundGenericType to "open" PackExpansionTypes into type variables (and a constraint to connect it to pattern/shape type variables);
  • Implements special inference/binding logic for pack expansion variables:
    • such variables are resolved via inference and bound to a opened pack expansion type they represent
  • Prevents matchTypes and TypeSimplifier from eagerly matching/transforming types with unresolved pack expansion variables.

Resolves: rdar://107996926
Resolves: rdar://107835125
Resolves: rdar://107675464
Resolves: rdar://107429079
Resolves: rdar://107835215
Resolves: rdar://107835086

@xedin xedin force-pushed the pack-expansion-type-var branch 2 times, most recently from bb7f01c to ed9bb09 Compare April 21, 2023 16:57
@xedin xedin force-pushed the pack-expansion-type-var branch from ed9bb09 to 536087d Compare April 25, 2023 22:24
@xedin xedin marked this pull request as ready for review April 25, 2023 22:24
@xedin
Copy link
Contributor Author

xedin commented Apr 25, 2023

@swift-ci please test

2 similar comments
@xedin
Copy link
Contributor Author

xedin commented Apr 26, 2023

@swift-ci please test

@xedin
Copy link
Contributor Author

xedin commented Apr 27, 2023

@swift-ci please test

Copy link
Member

@hborla hborla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome!!

@xedin
Copy link
Contributor Author

xedin commented May 2, 2023

@swift-ci please test macOS platform

1 similar comment
@xedin
Copy link
Contributor Author

xedin commented May 2, 2023

@swift-ci please test macOS platform

xedin added 18 commits May 2, 2023 09:31
The constraint solver would supply its own version of the function
that can check for pack expansion type variables as well.
This flag indicates that a type variable could only be bound
to PackExpansionType and nothing else.
Models `PackExpansionType` as a type variable that can only
bind to `PackExpansionType` and `expansion of` constraint that
connects expansion variable to its pattern, shape types.
…solved pack expansions

If a pattern type of a pack expansion doesn't have all of the "pack capable"
type variables bound, we don't know what the structure is yet and expansion
cannot be flattened.
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.
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.
…nstraints

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.
…expansion variables

`TypeBase::constainsPackExpansionType` cannot handle this because
it leaves in AST.
…are involved

The constraint solver has its own version of this method which
know how to deal with pack expansion type variables.
…olved pack expansions

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.
…pe variables

Such type variables always depend on pack expansion variables.
…roduce pattern type

The `transformWithPosition` would handle its flattening.
…iable is flattened

This is effectively the same as check `transformWithPosition` but
handles pack expansion type variables.
…sion variables

Pack expansion type variable can only ever have one binding
which is handled by \c resolvePackExpansion.

There is no need to iterate over other bindings here because
there is no use for contextual types (unlike closures that can
propagate contextual information into the body).
…open pack expansion types

Replace all `PackExpansionType` with a special type variable
which would be resolved once the solver determines that there
is enough contextual information.
xedin added 18 commits May 2, 2023 09:32
… with pack expansions

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.
`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.
…raint simplification

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.
…expansions

Just like in any other position, let's restore unresolved type variables
that represent generic parameters to their generic parameter type when
they are found in a pack expansion pattern type.
…element tuples

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.
… holes

If type variable that is being replaces allowed holes, the new one
should not lose this property.
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.
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.
…ed to arguments

Suggest to drop tuples, synthesized or remove extraneous arguments
based on pack shape mismatches.
If diagnostic references a `Pack{repeat ...}` unwrap it to underlying
pattern.
…pect a tuple argument

Diagnose situation when a single argument to tuple type is passed to
a value pack expansion parameter that expects distinct N elements:

```swift
struct S<each T> {
  func test(x: Int, _: repeat each T) {}
}

S<Int, String>().test(x: 42, (2, "b"))
```
Propagating holes to the shape helps avoid spurious diagnostics
about same-shape requirement failures.

Resolves: rdar://107675464
Situations like `repeat x` where `x` is `Int` where pack expansion
expression doesn't have any pack references.
Detect that pack expansion expression doesn't have any pack
references during constraint generation.

Resolves: rdar://107835215
@xedin xedin force-pushed the pack-expansion-type-var branch from cc9f5ce to bff6a89 Compare May 2, 2023 16:32
@xedin
Copy link
Contributor Author

xedin commented May 2, 2023

@swift-ci please test

@xedin
Copy link
Contributor Author

xedin commented May 2, 2023

Test clash with other PR :/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants