Skip to content

Commit 032c511

Browse files
committed
[ConstraintSystem] Add a PackElementOf constraint to delay mapping opened
element pattern types to pattern archetypes until after type variables are resolved.
1 parent 7354ad3 commit 032c511

File tree

7 files changed

+78
-19
lines changed

7 files changed

+78
-19
lines changed

Diff for: include/swift/Sema/Constraint.h

+4
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,9 @@ enum class ConstraintKind : char {
215215
/// Represents an AST node contained in a body of a function/closure.
216216
/// It only has an AST node to generate constraints and infer the type for.
217217
SyntacticElement,
218+
/// The first type is the opened pack element type of the second type, which
219+
/// is the pattern of a pack expansion type.
220+
PackElementOf,
218221
/// Do not add new uses of this, it only exists to retain compatibility for
219222
/// rdar://85263844.
220223
///
@@ -686,6 +689,7 @@ class Constraint final : public llvm::ilist_node<Constraint>,
686689
case ConstraintKind::OneWayBindParam:
687690
case ConstraintKind::DefaultClosureType:
688691
case ConstraintKind::UnresolvedMemberChainBase:
692+
case ConstraintKind::PackElementOf:
689693
return ConstraintClassification::Relational;
690694

691695
case ConstraintKind::ValueMember:

Diff for: include/swift/Sema/ConstraintSystem.h

+12
Original file line numberDiff line numberDiff line change
@@ -5501,6 +5501,18 @@ class ConstraintSystem {
55015501
TypeMatchOptions flags,
55025502
ConstraintLocatorBuilder locator);
55035503

5504+
/// Attempt to simplify a PackElementOf constraint.
5505+
///
5506+
/// Solving this constraint is delayed until the element type is fully
5507+
/// resolved with no type variables. The element type is then mapped out
5508+
/// of the opened element context and into the context of the surrounding
5509+
/// function, effecively substituting opened element archetypes with their
5510+
/// corresponding pack archetypes, and bound to the second type.
5511+
SolutionKind
5512+
simplifyPackElementOfConstraint(Type first, Type second,
5513+
TypeMatchOptions flags,
5514+
ConstraintLocatorBuilder locator);
5515+
55045516
/// Attempt to simplify the ApplicableFunction constraint.
55055517
SolutionKind simplifyApplicableFnConstraint(
55065518
Type type1, Type type2,

Diff for: lib/Sema/CSBindings.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1396,6 +1396,7 @@ void PotentialBindings::infer(Constraint *constraint) {
13961396
case ConstraintKind::SyntacticElement:
13971397
case ConstraintKind::Conjunction:
13981398
case ConstraintKind::BindTupleOfFunctionParams:
1399+
case ConstraintKind::PackElementOf:
13991400
// Constraints from which we can't do anything.
14001401
break;
14011402

Diff for: lib/Sema/CSGen.cpp

+4-14
Original file line numberDiff line numberDiff line change
@@ -2886,21 +2886,11 @@ namespace {
28862886
CS.setType(binding, type);
28872887
}
28882888

2889-
// Replace opened element archetypes with pack archetypes
2890-
// for the resulting type of the pack expansion.
28912889
auto elementResultType = CS.getType(expr->getPatternExpr());
2892-
auto patternTy = elementResultType.transform([&](Type type) -> Type {
2893-
auto *element = type->getAs<ElementArchetypeType>();
2894-
if (!element)
2895-
return type;
2896-
2897-
auto *elementParam = element->mapTypeOutOfContext()->getAs<GenericTypeParamType>();
2898-
auto *pack = GenericTypeParamType::get(/*isParameterPack*/true,
2899-
elementParam->getDepth(),
2900-
elementParam->getIndex(),
2901-
CS.getASTContext());
2902-
return CS.DC->mapTypeIntoContext(pack);
2903-
});
2890+
auto patternTy = CS.createTypeVariable(CS.getConstraintLocator(expr),
2891+
TVO_CanBindToHole);
2892+
CS.addConstraint(ConstraintKind::PackElementOf, elementResultType,
2893+
patternTy, CS.getConstraintLocator(expr));
29042894

29052895
// FIXME: Use a ShapeOf constraint here.
29062896
Type shapeType;

Diff for: lib/Sema/CSSimplify.cpp

+49
Original file line numberDiff line numberDiff line change
@@ -2424,6 +2424,7 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
24242424
case ConstraintKind::PropertyWrapper:
24252425
case ConstraintKind::SyntacticElement:
24262426
case ConstraintKind::BindTupleOfFunctionParams:
2427+
case ConstraintKind::PackElementOf:
24272428
llvm_unreachable("Bad constraint kind in matchTupleTypes()");
24282429
}
24292430

@@ -2595,6 +2596,7 @@ static bool matchFunctionRepresentations(FunctionType::ExtInfo einfo1,
25952596
case ConstraintKind::PropertyWrapper:
25962597
case ConstraintKind::SyntacticElement:
25972598
case ConstraintKind::BindTupleOfFunctionParams:
2599+
case ConstraintKind::PackElementOf:
25982600
return true;
25992601
}
26002602

@@ -3010,6 +3012,7 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
30103012
case ConstraintKind::PropertyWrapper:
30113013
case ConstraintKind::SyntacticElement:
30123014
case ConstraintKind::BindTupleOfFunctionParams:
3015+
case ConstraintKind::PackElementOf:
30133016
llvm_unreachable("Not a relational constraint");
30143017
}
30153018

@@ -6362,6 +6365,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
63626365
case ConstraintKind::PropertyWrapper:
63636366
case ConstraintKind::SyntacticElement:
63646367
case ConstraintKind::BindTupleOfFunctionParams:
6368+
case ConstraintKind::PackElementOf:
63656369
llvm_unreachable("Not a relational constraint");
63666370
}
63676371
}
@@ -8424,6 +8428,43 @@ ConstraintSystem::simplifyBindTupleOfFunctionParamsConstraint(
84248428
return SolutionKind::Solved;
84258429
}
84268430

8431+
ConstraintSystem::SolutionKind
8432+
ConstraintSystem::simplifyPackElementOfConstraint(Type first, Type second,
8433+
TypeMatchOptions flags,
8434+
ConstraintLocatorBuilder locator) {
8435+
auto elementType = simplifyType(first, flags);
8436+
auto *loc = getConstraintLocator(locator);
8437+
8438+
if (elementType->hasTypeVariable()) {
8439+
if (!flags.contains(TMF_GenerateConstraints))
8440+
return SolutionKind::Unsolved;
8441+
8442+
addUnsolvedConstraint(
8443+
Constraint::create(*this, ConstraintKind::PackElementOf,
8444+
first, second, loc));
8445+
8446+
return SolutionKind::Solved;
8447+
}
8448+
8449+
// Replace opened element archetypes with pack archetypes
8450+
// for the resulting type of the pack expansion.
8451+
auto patternType = elementType.transform([&](Type type) -> Type {
8452+
auto *element = type->getAs<ElementArchetypeType>();
8453+
if (!element)
8454+
return type;
8455+
8456+
auto *elementParam = element->mapTypeOutOfContext()->getAs<GenericTypeParamType>();
8457+
auto *pack = GenericTypeParamType::get(/*isParameterPack*/true,
8458+
elementParam->getDepth(),
8459+
elementParam->getIndex(),
8460+
this->getASTContext());
8461+
return this->DC->mapTypeIntoContext(pack);
8462+
});
8463+
8464+
addConstraint(ConstraintKind::Bind, second, patternType, locator);
8465+
return SolutionKind::Solved;
8466+
}
8467+
84278468
static bool isForKeyPathSubscript(ConstraintSystem &cs,
84288469
ConstraintLocator *locator) {
84298470
if (!locator || !locator->getAnchor())
@@ -13786,6 +13827,9 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
1378613827
return simplifyBindTupleOfFunctionParamsConstraint(first, second, subflags,
1378713828
locator);
1378813829

13830+
case ConstraintKind::PackElementOf:
13831+
return simplifyPackElementOfConstraint(first, second, subflags, locator);
13832+
1378913833
case ConstraintKind::ValueMember:
1379013834
case ConstraintKind::UnresolvedValueMember:
1379113835
case ConstraintKind::ValueWitness:
@@ -14355,6 +14399,11 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
1435514399
return simplifyBindTupleOfFunctionParamsConstraint(
1435614400
constraint.getFirstType(), constraint.getSecondType(), /*flags*/ None,
1435714401
constraint.getLocator());
14402+
14403+
case ConstraintKind::PackElementOf:
14404+
return simplifyPackElementOfConstraint(
14405+
constraint.getFirstType(), constraint.getSecondType(), /*flags*/None,
14406+
constraint.getLocator());
1435814407
}
1435914408

1436014409
llvm_unreachable("Unhandled ConstraintKind in switch.");

Diff for: lib/Sema/Constraint.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ Constraint::Constraint(ConstraintKind Kind, Type First, Type Second,
7979
case ConstraintKind::UnresolvedMemberChainBase:
8080
case ConstraintKind::PropertyWrapper:
8181
case ConstraintKind::BindTupleOfFunctionParams:
82+
case ConstraintKind::PackElementOf:
8283
assert(!First.isNull());
8384
assert(!Second.isNull());
8485
break;
@@ -165,6 +166,7 @@ Constraint::Constraint(ConstraintKind Kind, Type First, Type Second, Type Third,
165166
case ConstraintKind::PropertyWrapper:
166167
case ConstraintKind::SyntacticElement:
167168
case ConstraintKind::BindTupleOfFunctionParams:
169+
case ConstraintKind::PackElementOf:
168170
llvm_unreachable("Wrong constructor");
169171

170172
case ConstraintKind::KeyPath:
@@ -310,6 +312,7 @@ Constraint *Constraint::clone(ConstraintSystem &cs) const {
310312
case ConstraintKind::UnresolvedMemberChainBase:
311313
case ConstraintKind::PropertyWrapper:
312314
case ConstraintKind::BindTupleOfFunctionParams:
315+
case ConstraintKind::PackElementOf:
313316
return create(cs, getKind(), getFirstType(), getSecondType(), getLocator());
314317

315318
case ConstraintKind::ApplicableFunction:
@@ -546,6 +549,10 @@ void Constraint::print(llvm::raw_ostream &Out, SourceManager *sm, unsigned inden
546549
Out << " bind tuple of function params to ";
547550
break;
548551

552+
case ConstraintKind::PackElementOf:
553+
Out << " element of pack expansion pattern ";
554+
break;
555+
549556
case ConstraintKind::Disjunction:
550557
llvm_unreachable("disjunction handled above");
551558
case ConstraintKind::Conjunction:
@@ -710,6 +717,7 @@ gatherReferencedTypeVars(Constraint *constraint,
710717
case ConstraintKind::UnresolvedMemberChainBase:
711718
case ConstraintKind::PropertyWrapper:
712719
case ConstraintKind::BindTupleOfFunctionParams:
720+
case ConstraintKind::PackElementOf:
713721
constraint->getFirstType()->getTypeVariables(typeVars);
714722
constraint->getSecondType()->getTypeVariables(typeVars);
715723
break;

Diff for: test/Constraints/pack-expansion-expressions.swift

-5
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,9 @@ func forward<U...>(_ u: U...) -> (U...) {
2020
return tuplify(u...)
2121
}
2222

23-
// FIXME: This fails with opened element types. Add an ElementOf constraint to
24-
// handle cases where the pattern type is resolved after constraint generation
25-
// and mapped to pack archetypes in the solver.
26-
/*
2723
func forwardAndMap<U..., V...>(us u: U..., vs v: V...) -> ([(U, V)]...) {
2824
return tuplify([(u, v)]...)
2925
}
30-
*/
3126

3227
func variadicMap<T..., Result...>(_ t: T..., transform: ((T) -> Result)...) -> (Result...) {
3328
return (transform(t)...)

0 commit comments

Comments
 (0)