Skip to content

Commit 25fa312

Browse files
authored
Merge pull request #79529 from hamishknight/small-cleanup
[CS] Clean up pack expansion environment handling a little
2 parents 4ab5d26 + c69590f commit 25fa312

File tree

11 files changed

+212
-146
lines changed

11 files changed

+212
-146
lines changed

include/swift/Sema/CSTrail.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ LOCATOR_CHANGE(RecordedAppliedDisjunction, AppliedDisjunctions)
5555
LOCATOR_CHANGE(RecordedMatchCallArgumentResult, argumentMatchingChoices)
5656
LOCATOR_CHANGE(RecordedOpenedTypes, OpenedTypes)
5757
LOCATOR_CHANGE(RecordedOpenedExistentialType, OpenedExistentialTypes)
58-
LOCATOR_CHANGE(RecordedPackExpansionEnvironment, PackExpansionEnvironments)
5958
LOCATOR_CHANGE(RecordedDefaultedConstraint, DefaultedConstraints)
6059
LOCATOR_CHANGE(ResolvedOverload, ResolvedOverloads)
6160
LOCATOR_CHANGE(RecordedArgumentList, ArgumentLists)
@@ -95,7 +94,8 @@ CHANGE(AddedConversionRestriction)
9594
CHANGE(AddedFix)
9695
CHANGE(AddedFixedRequirement)
9796
CHANGE(RecordedOpenedPackExpansionType)
98-
CHANGE(RecordedPackEnvironment)
97+
CHANGE(RecordedPackElementExpansion)
98+
CHANGE(RecordedPackExpansionEnvironment)
9999
CHANGE(RecordedNodeType)
100100
CHANGE(RecordedKeyPathComponentType)
101101
CHANGE(RecordedResultBuilderTransform)
@@ -118,4 +118,4 @@ LAST_CHANGE(RetractedBinding)
118118
#undef BINDING_RELATION_CHANGE
119119
#undef SCORE_CHANGE
120120
#undef LAST_CHANGE
121-
#undef CHANGE
121+
#undef CHANGE

include/swift/Sema/CSTrail.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ class SolverTrail {
150150
ConstraintFix *TheFix;
151151
ConstraintLocator *TheLocator;
152152
PackExpansionType *TheExpansion;
153+
PackExpansionExpr *TheExpansionExpr;
153154
PackElementExpr *TheElement;
154155
Expr *TheExpr;
155156
Stmt *TheStmt;
@@ -213,7 +214,11 @@ class SolverTrail {
213214

214215
/// Create a change that recorded a mapping from a pack element expression
215216
/// to its parent expansion expression.
216-
static Change RecordedPackEnvironment(PackElementExpr *packElement);
217+
static Change RecordedPackElementExpansion(PackElementExpr *packElement);
218+
219+
/// Create a change that records the GenericEnvironment for a given
220+
/// PackExpansionExpr.
221+
static Change RecordedPackExpansionEnvironment(PackExpansionExpr *expr);
217222

218223
/// Create a change that recorded an assignment of a type to an AST node.
219224
static Change RecordedNodeType(ASTNode node, Type oldType);
@@ -307,4 +312,4 @@ class SolverTrail {
307312
} // namespace constraints
308313
} // namespace swift
309314

310-
#endif // SWIFT_SEMA_CSTRAIL_H
315+
#endif // SWIFT_SEMA_CSTRAIL_H

include/swift/Sema/ConstraintSystem.h

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,14 +1560,13 @@ class Solution {
15601560
llvm::DenseMap<PackExpansionType *, TypeVariableType *>
15611561
OpenedPackExpansionTypes;
15621562

1563-
/// The pack expansion environment that can open pack elements for
1564-
/// a given locator.
1565-
llvm::DenseMap<ConstraintLocator *, std::pair<UUID, Type>>
1563+
/// The generic environment that can open pack elements for a given
1564+
/// pack expansion.
1565+
llvm::DenseMap<PackExpansionExpr *, GenericEnvironment *>
15661566
PackExpansionEnvironments;
15671567

1568-
/// The pack expansion environment that can open a given pack element.
1569-
llvm::DenseMap<PackElementExpr *, PackExpansionExpr *>
1570-
PackEnvironments;
1568+
/// The pack expansion expression for a given pack element.
1569+
llvm::DenseMap<PackElementExpr *, PackExpansionExpr *> PackElementExpansions;
15711570

15721571
/// The locators of \c Defaultable constraints whose defaults were used.
15731572
llvm::DenseSet<ConstraintLocator *> DefaultedConstraints;
@@ -1811,6 +1810,11 @@ class Solution {
18111810
return Type();
18121811
}
18131812

1813+
/// Retrieve the generic environment for the opened element of a given pack
1814+
/// expansion, or \c nullptr if no environment was recorded.
1815+
GenericEnvironment *
1816+
getPackExpansionEnvironment(PackExpansionExpr *expr) const;
1817+
18141818
/// For a given locator describing a function argument conversion, or a
18151819
/// constraint within an argument conversion, returns information about the
18161820
/// application of the argument to its parameter. If the locator is not
@@ -2408,11 +2412,11 @@ class ConstraintSystem {
24082412
llvm::SmallDenseMap<PackExpansionType *, TypeVariableType *, 4>
24092413
OpenedPackExpansionTypes;
24102414

2411-
llvm::SmallDenseMap<ConstraintLocator *, std::pair<UUID, Type>, 4>
2415+
llvm::SmallDenseMap<PackExpansionExpr *, GenericEnvironment *, 4>
24122416
PackExpansionEnvironments;
24132417

24142418
llvm::SmallDenseMap<PackElementExpr *, PackExpansionExpr *, 2>
2415-
PackEnvironments;
2419+
PackElementExpansions;
24162420

24172421
llvm::SmallVector<GenericEnvironment *, 4> PackElementGenericEnvironments;
24182422

@@ -3371,25 +3375,39 @@ class ConstraintSystem {
33713375
void recordOpenedExistentialType(ConstraintLocator *locator,
33723376
OpenedArchetypeType *opened);
33733377

3374-
/// Get the opened element generic environment for the given locator.
3375-
GenericEnvironment *getPackElementEnvironment(ConstraintLocator *locator,
3376-
CanType shapeClass);
3378+
/// Retrieve the generic environment for the opened element of a given pack
3379+
/// expansion, or \c nullptr if no environment was recorded yet.
3380+
GenericEnvironment *
3381+
getPackExpansionEnvironment(PackExpansionExpr *expr) const;
3382+
3383+
/// Create a new opened element generic environment for the given pack
3384+
/// expansion.
3385+
GenericEnvironment *
3386+
createPackExpansionEnvironment(PackExpansionExpr *expr,
3387+
CanGenericTypeParamType shapeParam);
33773388

33783389
/// Update PackExpansionEnvironments and record a change in the trail.
3379-
void recordPackExpansionEnvironment(ConstraintLocator *locator,
3380-
std::pair<UUID, Type> uuidAndShape);
3390+
void recordPackExpansionEnvironment(PackExpansionExpr *expr,
3391+
GenericEnvironment *env);
33813392

3382-
/// Get the opened element generic environment for the given pack element.
3383-
PackExpansionExpr *getPackEnvironment(PackElementExpr *packElement) const;
3393+
/// Undo the above change.
3394+
void removePackExpansionEnvironment(PackExpansionExpr *expr) {
3395+
bool erased = PackExpansionEnvironments.erase(expr);
3396+
ASSERT(erased);
3397+
}
33843398

3385-
/// Associate an opened element generic environment to a pack element,
3386-
/// and record a change in the trail.
3387-
void addPackEnvironment(PackElementExpr *packElement,
3388-
PackExpansionExpr *packExpansion);
3399+
/// Get the pack expansion expr for the given pack element.
3400+
PackExpansionExpr *
3401+
getPackElementExpansion(PackElementExpr *packElement) const;
3402+
3403+
/// Associate a pack element with a given pack expansion, and record the
3404+
/// change in the trail.
3405+
void recordPackElementExpansion(PackElementExpr *packElement,
3406+
PackExpansionExpr *packExpansion);
33893407

33903408
/// Undo the above change.
3391-
void removePackEnvironment(PackElementExpr *packElement) {
3392-
bool erased = PackEnvironments.erase(packElement);
3409+
void removePackElementExpansion(PackElementExpr *packElement) {
3410+
bool erased = PackElementExpansions.erase(packElement);
33933411
ASSERT(erased);
33943412
}
33953413

@@ -5024,6 +5042,11 @@ class ConstraintSystem {
50245042
TypeMatchOptions flags,
50255043
ConstraintLocatorBuilder locator);
50265044

5045+
/// Attempt to match a pack element type with the fully resolved pattern type
5046+
/// for the pack expansion.
5047+
SolutionKind matchPackElementType(Type elementType, Type patternType,
5048+
ConstraintLocatorBuilder locator);
5049+
50275050
/// Attempt to simplify a PackElementOf constraint.
50285051
///
50295052
/// Solving this constraint is delayed until the element type is fully

lib/Sema/CSApply.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3942,21 +3942,15 @@ namespace {
39423942
}
39433943

39443944
Expr *visitPackExpansionExpr(PackExpansionExpr *expr) {
3945-
simplifyExprType(expr);
3946-
39473945
// Set the opened pack element environment for this pack expansion.
3948-
auto expansionTy = cs.getType(expr)->castTo<PackExpansionType>();
3949-
auto *locator = cs.getConstraintLocator(expr);
3950-
auto *environment = cs.getPackElementEnvironment(locator,
3951-
expansionTy->getCountType()->getCanonicalType());
3952-
39533946
// Assert that we have an opened element environment, otherwise we'll get
39543947
// an ASTVerifier crash when pack archetypes or element archetypes appear
39553948
// inside the pack expansion expression.
3949+
auto *environment = solution.getPackExpansionEnvironment(expr);
39563950
assert(environment);
39573951
expr->setGenericEnvironment(environment);
39583952

3959-
return expr;
3953+
return simplifyExprType(expr);
39603954
}
39613955

39623956
Expr *visitPackElementExpr(PackElementExpr *expr) {

lib/Sema/CSGen.cpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -902,10 +902,10 @@ TypeVarRefCollector::walkToExprPre(Expr *expr) {
902902
}
903903

904904
if (auto *packElement = getAsExpr<PackElementExpr>(expr)) {
905-
// If environment hasn't been established yet, it means that pack expansion
905+
// If expansion hasn't been established yet, it means that pack expansion
906906
// appears inside of this closure.
907-
if (auto *outerEnvironment = CS.getPackEnvironment(packElement))
908-
inferTypeVars(outerEnvironment);
907+
if (auto *outerExpansion = CS.getPackElementExpansion(packElement))
908+
inferTypeVars(outerExpansion);
909909
}
910910

911911
return Action::Continue(expr);
@@ -1214,9 +1214,8 @@ namespace {
12141214
SmallVector<ASTNode, 2> expandedPacks;
12151215
collectExpandedPacks(expr, expandedPacks);
12161216
for (auto pack : expandedPacks) {
1217-
if (auto *elementExpr = getAsExpr<PackElementExpr>(pack)) {
1218-
CS.addPackEnvironment(elementExpr, expr);
1219-
}
1217+
if (auto *elementExpr = getAsExpr<PackElementExpr>(pack))
1218+
CS.recordPackElementExpansion(elementExpr, expr);
12201219
}
12211220

12221221
auto *patternLoc = CS.getConstraintLocator(
@@ -3239,15 +3238,15 @@ namespace {
32393238

32403239
Type visitPackElementExpr(PackElementExpr *expr) {
32413240
auto packType = CS.getType(expr->getPackRefExpr());
3242-
auto *packEnvironment = CS.getPackEnvironment(expr);
3241+
auto *packExpansion = CS.getPackElementExpansion(expr);
32433242
auto elementType = openPackElement(
3244-
packType, CS.getConstraintLocator(expr), packEnvironment);
3245-
if (packEnvironment) {
3243+
packType, CS.getConstraintLocator(expr), packExpansion);
3244+
if (packExpansion) {
32463245
auto expansionType =
3247-
CS.getType(packEnvironment)->castTo<PackExpansionType>();
3246+
CS.getType(packExpansion)->castTo<PackExpansionType>();
32483247
CS.addConstraint(ConstraintKind::ShapeOf, expansionType->getCountType(),
32493248
packType,
3250-
CS.getConstraintLocator(packEnvironment,
3249+
CS.getConstraintLocator(packExpansion,
32513250
ConstraintLocator::PackShape));
32523251
} else {
32533252
CS.recordFix(AllowInvalidPackReference::create(

lib/Sema/CSSimplify.cpp

Lines changed: 59 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -9626,6 +9626,63 @@ ConstraintSystem::simplifyBindTupleOfFunctionParamsConstraint(
96269626
return SolutionKind::Solved;
96279627
}
96289628

9629+
ConstraintSystem::SolutionKind
9630+
ConstraintSystem::matchPackElementType(Type elementType, Type patternType,
9631+
ConstraintLocatorBuilder locator) {
9632+
auto tryFix = [&](llvm::function_ref<ConstraintFix *(void)> fix) {
9633+
if (!shouldAttemptFixes())
9634+
return SolutionKind::Error;
9635+
9636+
if (recordFix(fix()))
9637+
return SolutionKind::Error;
9638+
9639+
recordAnyTypeVarAsPotentialHole(elementType);
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);
9676+
}
9677+
9678+
auto expectedElementTy =
9679+
genericEnv->mapContextualPackTypeIntoElementContext(patternType);
9680+
assert(!expectedElementTy->is<PackType>());
9681+
9682+
addConstraint(ConstraintKind::Equal, elementType, expectedElementTy, locator);
9683+
return SolutionKind::Solved;
9684+
}
9685+
96299686
ConstraintSystem::SolutionKind
96309687
ConstraintSystem::simplifyPackElementOfConstraint(Type first, Type second,
96319688
TypeMatchOptions flags,
@@ -9660,46 +9717,8 @@ ConstraintSystem::simplifyPackElementOfConstraint(Type first, Type second,
96609717
}
96619718

96629719
// Let's try to resolve element type based on the pattern type.
9663-
if (!patternType->hasTypeVariable()) {
9664-
auto *loc = getConstraintLocator(locator);
9665-
auto shapeClass = patternType->getReducedShape();
9666-
auto *elementEnv = getPackElementEnvironment(loc, shapeClass);
9667-
9668-
// Without an opened element environment, we cannot derive the
9669-
// element binding.
9670-
if (!elementEnv) {
9671-
if (!shouldAttemptFixes())
9672-
return SolutionKind::Error;
9673-
9674-
// `each` was applied to a concrete type.
9675-
if (!shapeClass->is<PackArchetypeType>()) {
9676-
if (recordFix(AllowInvalidPackElement::create(*this, patternType, loc)))
9677-
return SolutionKind::Error;
9678-
} else {
9679-
auto envShape = PackExpansionEnvironments.find(loc);
9680-
if (envShape == PackExpansionEnvironments.end()) {
9681-
return SolutionKind::Error;
9682-
}
9683-
auto *fix = SkipSameShapeRequirement::create(
9684-
*this, envShape->second.second, shapeClass,
9685-
getConstraintLocator(loc, ConstraintLocator::PackShape));
9686-
if (recordFix(fix)) {
9687-
return SolutionKind::Error;
9688-
}
9689-
}
9690-
9691-
recordAnyTypeVarAsPotentialHole(elementType);
9692-
return SolutionKind::Solved;
9693-
}
9694-
9695-
auto expectedElementTy =
9696-
elementEnv->mapContextualPackTypeIntoElementContext(patternType);
9697-
assert(!expectedElementTy->is<PackType>());
9698-
9699-
addConstraint(ConstraintKind::Equal, elementType, expectedElementTy,
9700-
locator);
9701-
return SolutionKind::Solved;
9702-
}
9720+
if (!patternType->hasTypeVariable())
9721+
return matchPackElementType(elementType, patternType, locator);
97039722

97049723
// Otherwise we are inferred or checking pattern type.
97059724

lib/Sema/CSSolver.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,8 @@ Solution ConstraintSystem::finalize() {
256256
solution.PackExpansionEnvironments.insert(env);
257257
}
258258

259-
for (const auto &packEnv : PackEnvironments)
260-
solution.PackEnvironments.insert(packEnv);
259+
for (const auto &packEnv : PackElementExpansions)
260+
solution.PackElementExpansions.insert(packEnv);
261261

262262
for (const auto &synthesized : SynthesizedConformances) {
263263
solution.SynthesizedConformances.insert(synthesized);
@@ -355,10 +355,10 @@ void ConstraintSystem::replaySolution(const Solution &solution,
355355
recordPackExpansionEnvironment(expansion.first, expansion.second);
356356
}
357357

358-
// Register the solutions's pack environments.
359-
for (auto &packEnvironment : solution.PackEnvironments) {
360-
if (PackEnvironments.count(packEnvironment.first) == 0)
361-
addPackEnvironment(packEnvironment.first, packEnvironment.second);
358+
// Register the solutions's pack expansions.
359+
for (auto &packEnvironment : solution.PackElementExpansions) {
360+
if (PackElementExpansions.count(packEnvironment.first) == 0)
361+
recordPackElementExpansion(packEnvironment.first, packEnvironment.second);
362362
}
363363

364364
// Register the defaulted type variables.

lib/Sema/CSSyntacticElement.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,8 @@ class TypeVariableRefFinder : public ASTWalker {
188188
// that reference pack elements have to bring expansion's shape
189189
// type in scope to make sure that the shapes match.
190190
if (auto *packElement = getAsExpr<PackElementExpr>(expr)) {
191-
if (auto *outerEnvironment = CS.getPackEnvironment(packElement)) {
192-
auto *expansionTy = CS.simplifyType(CS.getType(outerEnvironment))
191+
if (auto *outerExpansion = CS.getPackElementExpansion(packElement)) {
192+
auto *expansionTy = CS.simplifyType(CS.getType(outerExpansion))
193193
->castTo<PackExpansionType>();
194194
expansionTy->getCountType()->getTypeVariables(ReferencedVars);
195195
}

0 commit comments

Comments
 (0)