Skip to content

Commit bf57556

Browse files
hborlasimanerush
authored andcommitted
[Constraint System] Fix the shape class and context substitiutions for
opened element generic environments containing same-element requirements.
1 parent 5d4162e commit bf57556

File tree

6 files changed

+47
-16
lines changed

6 files changed

+47
-16
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3759,6 +3759,11 @@ class ConstraintSystem {
37593759
RememberChoice_t rememberChoice,
37603760
ConstraintLocatorBuilder locator,
37613761
ConstraintFix *compatFix = nullptr);
3762+
3763+
/// Add a materialize constraint for a pack expansion.
3764+
TypeVariableType *
3765+
addMaterializePackExpansionConstraint(Type patternType,
3766+
ConstraintLocatorBuilder locator);
37623767

37633768
/// Add a disjunction constraint.
37643769
void

lib/AST/GenericSignature.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,16 @@ void GenericSignatureImpl::forEachParam(
105105

106106
for (auto req : getRequirements()) {
107107
GenericTypeParamType *gp;
108+
bool isCanonical = false;
108109
switch (req.getKind()) {
109110
case RequirementKind::SameType: {
111+
if (req.getSecondType()->isParameterPack() !=
112+
req.getFirstType()->isParameterPack()) {
113+
// This is a same-element requirement, which does not make
114+
// type parameters non-canonical.
115+
isCanonical = true;
116+
}
117+
110118
if (auto secondGP = req.getSecondType()->getAs<GenericTypeParamType>()) {
111119
// If two generic parameters are same-typed, then the right-hand one
112120
// is non-canonical.
@@ -136,7 +144,7 @@ void GenericSignatureImpl::forEachParam(
136144
}
137145

138146
unsigned index = GenericParamKey(gp).findIndexIn(genericParams);
139-
genericParamsAreCanonical[index] = false;
147+
genericParamsAreCanonical[index] = isCanonical;
140148
}
141149

142150
// Call the callback with each parameter and the result of the above analysis.

lib/Sema/CSApply.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3843,6 +3843,11 @@ namespace {
38433843
auto *locator = cs.getConstraintLocator(expr);
38443844
auto *environment = cs.getPackElementEnvironment(locator,
38453845
expansionTy->getCountType()->getCanonicalType());
3846+
3847+
// Assert that we have an opened element environment, otherwise we'll get
3848+
// an ASTVerifier crash when pack archetypes or element archetypes appear
3849+
// inside the pack expansion expression.
3850+
assert(environment);
38463851
expr->setGenericEnvironment(environment);
38473852

38483853
return expr;

lib/Sema/CSGen.cpp

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3198,18 +3198,9 @@ namespace {
31983198
auto expansionType =
31993199
CS.getType(packEnvironment)->castTo<PackExpansionType>();
32003200
CS.addConstraint(ConstraintKind::ShapeOf, expansionType->getCountType(),
3201-
elementType,
3201+
packType,
32023202
CS.getConstraintLocator(packEnvironment,
32033203
ConstraintLocator::PackShape));
3204-
auto *elementShape = CS.createTypeVariable(
3205-
CS.getConstraintLocator(expr, ConstraintLocator::PackShape),
3206-
TVO_CanBindToPack);
3207-
CS.addConstraint(
3208-
ConstraintKind::ShapeOf, elementShape, elementType,
3209-
CS.getConstraintLocator(expr, ConstraintLocator::PackShape));
3210-
CS.addConstraint(
3211-
ConstraintKind::Equal, elementShape, expansionType->getCountType(),
3212-
CS.getConstraintLocator(expr, ConstraintLocator::PackShape));
32133204
} else {
32143205
CS.recordFix(AllowInvalidPackReference::create(
32153206
CS, packType, CS.getConstraintLocator(expr->getPackRefExpr())));

lib/Sema/CSSimplify.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9313,11 +9313,7 @@ ConstraintSystem::simplifyPackElementOfConstraint(Type first, Type second,
93139313
}
93149314

93159315
if (isSingleUnlabeledPackExpansionTuple(patternType)) {
9316-
auto *packVar =
9317-
createTypeVariable(getConstraintLocator(locator), TVO_CanBindToPack);
9318-
addConstraint(ConstraintKind::MaterializePackExpansion, patternType,
9319-
packVar,
9320-
getConstraintLocator(locator, {ConstraintLocator::Member}));
9316+
auto *packVar = addMaterializePackExpansionConstraint(patternType, locator);
93219317
addConstraint(ConstraintKind::PackElementOf, elementType, packVar, locator);
93229318
return SolutionKind::Solved;
93239319
}
@@ -13440,6 +13436,12 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyShapeOfConstraint(
1344013436
return SolutionKind::Solved;
1344113437
}
1344213438

13439+
if (isSingleUnlabeledPackExpansionTuple(packTy)) {
13440+
auto *packVar = addMaterializePackExpansionConstraint(packTy, locator);
13441+
addConstraint(ConstraintKind::ShapeOf, shapeTy, packVar, locator);
13442+
return SolutionKind::Solved;
13443+
}
13444+
1344313445
// Map element archetypes to the pack context to check for equality.
1344413446
if (packTy->hasElementArchetype()) {
1344513447
auto *packEnv = DC->getGenericEnvironmentOfContext();
@@ -15623,6 +15625,16 @@ void ConstraintSystem::addExplicitConversionConstraint(
1562315625
addDisjunctionConstraint(constraints, locator, rememberChoice);
1562415626
}
1562515627

15628+
TypeVariableType *ConstraintSystem::addMaterializePackExpansionConstraint(
15629+
Type patternType, ConstraintLocatorBuilder locator) {
15630+
assert(isSingleUnlabeledPackExpansionTuple(patternType));
15631+
TypeVariableType *packVar =
15632+
createTypeVariable(getConstraintLocator(locator), TVO_CanBindToPack);
15633+
addConstraint(ConstraintKind::MaterializePackExpansion, patternType, packVar,
15634+
getConstraintLocator(locator, {ConstraintLocator::Member}));
15635+
return packVar;
15636+
}
15637+
1562615638
ConstraintSystem::SolutionKind
1562715639
ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
1562815640
auto matchKind = constraint.getKind();

test/Constraints/pack-expansion-expressions.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,3 +734,13 @@ do {
734734
}
735735
}
736736
}
737+
738+
// Pack Iteration
739+
do {
740+
func test<each T>(_ t: repeat each T) {
741+
func nested() -> (repeat (Int, each T)) {}
742+
for (x, y) in repeat each nested() {}
743+
// expected-warning@-1 {{immutable value 'x' was never used; consider replacing with '_' or removing it}}
744+
// expected-warning@-2 {{immutable value 'y' was never used; consider replacing with '_' or removing it}}
745+
}
746+
}

0 commit comments

Comments
 (0)