@@ -9629,43 +9629,57 @@ ConstraintSystem::simplifyBindTupleOfFunctionParamsConstraint(
9629
9629
ConstraintSystem::SolutionKind
9630
9630
ConstraintSystem::matchPackElementType(Type elementType, Type patternType,
9631
9631
ConstraintLocatorBuilder locator) {
9632
- auto *loc = getConstraintLocator(locator);
9633
- auto shapeClass = patternType->getReducedShape();
9634
- auto *elementEnv = getPackElementEnvironment(loc, shapeClass);
9635
-
9636
- // Without an opened element environment, we cannot derive the
9637
- // element binding.
9638
- if (!elementEnv) {
9632
+ auto tryFix = [&](llvm::function_ref<ConstraintFix *(void)> fix) {
9639
9633
if (!shouldAttemptFixes())
9640
9634
return SolutionKind::Error;
9641
9635
9642
- // `each` was applied to a concrete type.
9643
- if (!shapeClass->is<PackArchetypeType>()) {
9644
- if (recordFix(AllowInvalidPackElement::create(*this, patternType, loc)))
9645
- return SolutionKind::Error;
9646
- } else {
9647
- auto envShape = PackExpansionEnvironments.find(loc);
9648
- if (envShape == PackExpansionEnvironments.end()) {
9649
- return SolutionKind::Error;
9650
- }
9651
- auto *fix = SkipSameShapeRequirement::create(
9652
- *this, envShape->second.second, shapeClass,
9653
- getConstraintLocator(loc, ConstraintLocator::PackShape));
9654
- if (recordFix(fix)) {
9655
- return SolutionKind::Error;
9656
- }
9657
- }
9636
+ if (recordFix(fix()))
9637
+ return SolutionKind::Error;
9658
9638
9659
9639
recordAnyTypeVarAsPotentialHole(elementType);
9660
9640
return SolutionKind::Solved;
9641
+ };
9642
+
9643
+ auto *loc = getConstraintLocator(locator);
9644
+ ASSERT(loc->directlyAt<PackExpansionExpr>());
9645
+ auto *packExpansion = castToExpr<PackExpansionExpr>(loc->getAnchor());
9646
+
9647
+ ASSERT(!patternType->hasTypeVariable());
9648
+ auto shapeClass = patternType->getReducedShape();
9649
+
9650
+ // `each` was applied to a concrete type.
9651
+ if (!shapeClass->is<PackArchetypeType>()) {
9652
+ return tryFix([&]() {
9653
+ return AllowInvalidPackElement::create(*this, patternType, loc);
9654
+ });
9655
+ }
9656
+
9657
+ auto shapeParam = CanGenericTypeParamType(cast<GenericTypeParamType>(
9658
+ shapeClass->mapTypeOutOfContext()->getCanonicalType()));
9659
+
9660
+ auto *genericEnv = getPackExpansionEnvironment(packExpansion);
9661
+ if (genericEnv) {
9662
+ if (shapeParam != genericEnv->getOpenedElementShapeClass()) {
9663
+ return tryFix([&]() {
9664
+ auto envShape = genericEnv->mapTypeIntoContext(
9665
+ genericEnv->getOpenedElementShapeClass());
9666
+ if (auto *pack = dyn_cast<PackType>(envShape))
9667
+ envShape = pack->unwrapSingletonPackExpansion()->getPatternType();
9668
+
9669
+ return SkipSameShapeRequirement::create(
9670
+ *this, envShape, shapeClass,
9671
+ getConstraintLocator(loc, ConstraintLocator::PackShape));
9672
+ });
9673
+ }
9674
+ } else {
9675
+ genericEnv = createPackExpansionEnvironment(packExpansion, shapeParam);
9661
9676
}
9662
9677
9663
9678
auto expectedElementTy =
9664
- elementEnv ->mapContextualPackTypeIntoElementContext(patternType);
9679
+ genericEnv ->mapContextualPackTypeIntoElementContext(patternType);
9665
9680
assert(!expectedElementTy->is<PackType>());
9666
9681
9667
- addConstraint(ConstraintKind::Equal, elementType, expectedElementTy,
9668
- locator);
9682
+ addConstraint(ConstraintKind::Equal, elementType, expectedElementTy, locator);
9669
9683
return SolutionKind::Solved;
9670
9684
}
9671
9685
0 commit comments