@@ -129,12 +129,20 @@ static bool isPackExpansionType(Type type) {
129
129
130
130
bool constraints::isSingleUnlabeledPackExpansionTuple(Type type) {
131
131
auto *tuple = type->getRValueType()->getAs<TupleType>();
132
- // TODO: drop no name requirement
133
132
return tuple && (tuple->getNumElements() == 1) &&
134
133
isPackExpansionType(tuple->getElementType(0)) &&
135
134
!tuple->getElement(0).hasName();
136
135
}
137
136
137
+ Type constraints::getPatternTypeOfSingleUnlabeledPackExpansionTuple(Type type) {
138
+ if (!isSingleUnlabeledPackExpansionTuple(type)) {
139
+ return {};
140
+ }
141
+ auto tuple = type->getRValueType()->castTo<TupleType>();
142
+ auto *expansion = tuple->getElementType(0)->castTo<PackExpansionType>();
143
+ return expansion->getPatternType();
144
+ }
145
+
138
146
static bool containsPackExpansionType(ArrayRef<AnyFunctionType::Param> params) {
139
147
return llvm::any_of(params, [&](const auto ¶m) {
140
148
return isPackExpansionType(param.getPlainType());
@@ -2283,6 +2291,7 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
2283
2291
case ConstraintKind::ShapeOf:
2284
2292
case ConstraintKind::ExplicitGenericArguments:
2285
2293
case ConstraintKind::SameShape:
2294
+ case ConstraintKind::MaterializePackExpansion:
2286
2295
llvm_unreachable("Bad constraint kind in matchTupleTypes()");
2287
2296
}
2288
2297
@@ -2643,6 +2652,7 @@ static bool matchFunctionRepresentations(FunctionType::ExtInfo einfo1,
2643
2652
case ConstraintKind::ShapeOf:
2644
2653
case ConstraintKind::ExplicitGenericArguments:
2645
2654
case ConstraintKind::SameShape:
2655
+ case ConstraintKind::MaterializePackExpansion:
2646
2656
return true;
2647
2657
}
2648
2658
@@ -3161,6 +3171,7 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
3161
3171
case ConstraintKind::ShapeOf:
3162
3172
case ConstraintKind::ExplicitGenericArguments:
3163
3173
case ConstraintKind::SameShape:
3174
+ case ConstraintKind::MaterializePackExpansion:
3164
3175
llvm_unreachable("Not a relational constraint");
3165
3176
}
3166
3177
@@ -6827,6 +6838,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
6827
6838
case ConstraintKind::ShapeOf:
6828
6839
case ConstraintKind::ExplicitGenericArguments:
6829
6840
case ConstraintKind::SameShape:
6841
+ case ConstraintKind::MaterializePackExpansion:
6830
6842
llvm_unreachable("Not a relational constraint");
6831
6843
}
6832
6844
}
@@ -9149,13 +9161,13 @@ ConstraintSystem::simplifyPackElementOfConstraint(Type first, Type second,
9149
9161
}
9150
9162
9151
9163
if (isSingleUnlabeledPackExpansionTuple(patternType)) {
9152
- auto *elementVar =
9153
- createTypeVariable(getConstraintLocator(locator), /*options=*/0 );
9154
- addValueMemberConstraint(
9155
- patternType, DeclNameRef(getASTContext().Id_element), elementVar, DC ,
9156
- FunctionRefKind::Unapplied , {},
9157
- getConstraintLocator(locator, {ConstraintLocator::Member}) );
9158
- patternType = elementVar ;
9164
+ auto *packVar =
9165
+ createTypeVariable(getConstraintLocator(locator), TVO_CanBindToPack );
9166
+ addConstraint(ConstraintKind::MaterializePackExpansion, patternType,
9167
+ packVar ,
9168
+ getConstraintLocator(locator , {ConstraintLocator::Member}));
9169
+ addConstraint(ConstraintKind::PackElementOf, elementType, packVar, locator );
9170
+ return SolutionKind::Solved ;
9159
9171
}
9160
9172
9161
9173
// Let's try to resolve element type based on the pattern type.
@@ -9174,11 +9186,19 @@ ConstraintSystem::simplifyPackElementOfConstraint(Type first, Type second,
9174
9186
if (!shapeClass->is<PackArchetypeType>()) {
9175
9187
if (recordFix(AllowInvalidPackElement::create(*this, patternType, loc)))
9176
9188
return SolutionKind::Error;
9189
+ } else {
9190
+ auto envShape = PackExpansionEnvironments.find(loc);
9191
+ if (envShape == PackExpansionEnvironments.end()) {
9192
+ return SolutionKind::Error;
9193
+ }
9194
+ auto *fix = SkipSameShapeRequirement::create(
9195
+ *this, envShape->second.second, shapeClass,
9196
+ getConstraintLocator(loc, ConstraintLocator::PackShape));
9197
+ if (recordFix(fix)) {
9198
+ return SolutionKind::Error;
9199
+ }
9177
9200
}
9178
9201
9179
- // Only other posibility is that there is a shape mismatch between
9180
- // elements of the pack expansion pattern which is detected separately.
9181
-
9182
9202
recordAnyTypeVarAsPotentialHole(elementType);
9183
9203
return SolutionKind::Solved;
9184
9204
}
@@ -13551,6 +13571,37 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifySameShapeConstraint(
13551
13571
return SolutionKind::Error;
13552
13572
}
13553
13573
13574
+ ConstraintSystem::SolutionKind
13575
+ ConstraintSystem::simplifyMaterializePackExpansionConstraint(
13576
+ Type type1, Type type2, TypeMatchOptions flags,
13577
+ ConstraintLocatorBuilder locator) {
13578
+ auto formUnsolved = [&]() {
13579
+ // If we're supposed to generate constraints, do so.
13580
+ if (flags.contains(TMF_GenerateConstraints)) {
13581
+ auto *explictGenericArgs =
13582
+ Constraint::create(*this, ConstraintKind::MaterializePackExpansion,
13583
+ type1, type2, getConstraintLocator(locator));
13584
+
13585
+ addUnsolvedConstraint(explictGenericArgs);
13586
+ return SolutionKind::Solved;
13587
+ }
13588
+
13589
+ return SolutionKind::Unsolved;
13590
+ };
13591
+
13592
+ type1 = simplifyType(type1);
13593
+ if (type1->hasTypeVariable()) {
13594
+ return formUnsolved();
13595
+ }
13596
+ if (auto patternType =
13597
+ getPatternTypeOfSingleUnlabeledPackExpansionTuple(type1)) {
13598
+ addConstraint(ConstraintKind::Equal, patternType, type2, locator);
13599
+ return SolutionKind::Solved;
13600
+ }
13601
+
13602
+ return SolutionKind::Error;
13603
+ }
13604
+
13554
13605
ConstraintSystem::SolutionKind
13555
13606
ConstraintSystem::simplifyExplicitGenericArgumentsConstraint(
13556
13607
Type type1, Type type2, TypeMatchOptions flags,
@@ -15178,6 +15229,10 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
15178
15229
return simplifyExplicitGenericArgumentsConstraint(
15179
15230
first, second, subflags, locator);
15180
15231
15232
+ case ConstraintKind::MaterializePackExpansion:
15233
+ return simplifyMaterializePackExpansionConstraint(first, second, subflags,
15234
+ locator);
15235
+
15181
15236
case ConstraintKind::ValueMember:
15182
15237
case ConstraintKind::UnresolvedValueMember:
15183
15238
case ConstraintKind::ValueWitness:
@@ -15757,6 +15812,11 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
15757
15812
return simplifyExplicitGenericArgumentsConstraint(
15758
15813
constraint.getFirstType(), constraint.getSecondType(),
15759
15814
/*flags*/ llvm::None, constraint.getLocator());
15815
+
15816
+ case ConstraintKind::MaterializePackExpansion:
15817
+ return simplifyMaterializePackExpansionConstraint(
15818
+ constraint.getFirstType(), constraint.getSecondType(),
15819
+ /*flags*/ llvm::None, constraint.getLocator());
15760
15820
}
15761
15821
15762
15822
llvm_unreachable("Unhandled ConstraintKind in switch.");
0 commit comments