@@ -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.
@@ -9175,11 +9187,19 @@ ConstraintSystem::simplifyPackElementOfConstraint(Type first, Type second,
9175
9187
if (!shapeClass->is<PackArchetypeType>()) {
9176
9188
if (recordFix(AllowInvalidPackElement::create(*this, patternType, loc)))
9177
9189
return SolutionKind::Error;
9190
+ } else {
9191
+ auto envShape = PackExpansionEnvironments.find(loc);
9192
+ if (envShape == PackExpansionEnvironments.end()) {
9193
+ return SolutionKind::Error;
9194
+ }
9195
+ auto *fix = SkipSameShapeRequirement::create(
9196
+ *this, envShape->second.second, shapeClass,
9197
+ getConstraintLocator(loc, ConstraintLocator::PackShape));
9198
+ if (recordFix(fix)) {
9199
+ return SolutionKind::Error;
9200
+ }
9178
9201
}
9179
9202
9180
- // Only other posibility is that there is a shape mismatch between
9181
- // elements of the pack expansion pattern which is detected separately.
9182
-
9183
9203
recordAnyTypeVarAsPotentialHole(elementType);
9184
9204
return SolutionKind::Solved;
9185
9205
}
@@ -13552,6 +13572,37 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifySameShapeConstraint(
13552
13572
return SolutionKind::Error;
13553
13573
}
13554
13574
13575
+ ConstraintSystem::SolutionKind
13576
+ ConstraintSystem::simplifyMaterializePackExpansionConstraint(
13577
+ Type type1, Type type2, TypeMatchOptions flags,
13578
+ ConstraintLocatorBuilder locator) {
13579
+ auto formUnsolved = [&]() {
13580
+ // If we're supposed to generate constraints, do so.
13581
+ if (flags.contains(TMF_GenerateConstraints)) {
13582
+ auto *explictGenericArgs =
13583
+ Constraint::create(*this, ConstraintKind::MaterializePackExpansion,
13584
+ type1, type2, getConstraintLocator(locator));
13585
+
13586
+ addUnsolvedConstraint(explictGenericArgs);
13587
+ return SolutionKind::Solved;
13588
+ }
13589
+
13590
+ return SolutionKind::Unsolved;
13591
+ };
13592
+
13593
+ type1 = simplifyType(type1);
13594
+ if (type1->hasTypeVariable()) {
13595
+ return formUnsolved();
13596
+ }
13597
+ if (auto patternType =
13598
+ getPatternTypeOfSingleUnlabeledPackExpansionTuple(type1)) {
13599
+ addConstraint(ConstraintKind::Equal, patternType, type2, locator);
13600
+ return SolutionKind::Solved;
13601
+ }
13602
+
13603
+ return SolutionKind::Error;
13604
+ }
13605
+
13555
13606
ConstraintSystem::SolutionKind
13556
13607
ConstraintSystem::simplifyExplicitGenericArgumentsConstraint(
13557
13608
Type type1, Type type2, TypeMatchOptions flags,
@@ -15179,6 +15230,10 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
15179
15230
return simplifyExplicitGenericArgumentsConstraint(
15180
15231
first, second, subflags, locator);
15181
15232
15233
+ case ConstraintKind::MaterializePackExpansion:
15234
+ return simplifyMaterializePackExpansionConstraint(first, second, subflags,
15235
+ locator);
15236
+
15182
15237
case ConstraintKind::ValueMember:
15183
15238
case ConstraintKind::UnresolvedValueMember:
15184
15239
case ConstraintKind::ValueWitness:
@@ -15758,6 +15813,11 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
15758
15813
return simplifyExplicitGenericArgumentsConstraint(
15759
15814
constraint.getFirstType(), constraint.getSecondType(),
15760
15815
/*flags*/ llvm::None, constraint.getLocator());
15816
+
15817
+ case ConstraintKind::MaterializePackExpansion:
15818
+ return simplifyMaterializePackExpansionConstraint(
15819
+ constraint.getFirstType(), constraint.getSecondType(),
15820
+ /*flags*/ llvm::None, constraint.getLocator());
15761
15821
}
15762
15822
15763
15823
llvm_unreachable("Unhandled ConstraintKind in switch.");
0 commit comments