Skip to content

Commit 6e28f99

Browse files
committed
[ConstraintSystem] Create opened pack element generic environments lazily
in the constraint system.
1 parent 319ae65 commit 6e28f99

10 files changed

+63
-69
lines changed

include/swift/Sema/ConstraintLocator.h

-15
Original file line numberDiff line numberDiff line change
@@ -690,21 +690,6 @@ class LocatorPathElt::PackElement final : public StoredIntegerElement<1> {
690690
}
691691
};
692692

693-
class LocatorPathElt::OpenedPackElement final
694-
: public StoredPointerElement<GenericEnvironment> {
695-
public:
696-
OpenedPackElement(GenericEnvironment *env)
697-
: StoredPointerElement(PathElementKind::OpenedPackElement, env) {}
698-
699-
GenericEnvironment *getGenericEnvironment() const {
700-
return getStoredPointer();
701-
}
702-
703-
static bool classof(const LocatorPathElt *elt) {
704-
return elt->getKind() == PathElementKind::OpenedPackElement;
705-
}
706-
};
707-
708693
class LocatorPathElt::KeyPathComponent final : public StoredIntegerElement<1> {
709694
public:
710695
KeyPathComponent(unsigned index)

include/swift/Sema/ConstraintLocatorPathElts.def

-3
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,6 @@ CUSTOM_LOCATOR_PATH_ELT(PackType)
195195
/// An element of a pack type - the T in <T, U, V, ...>
196196
CUSTOM_LOCATOR_PATH_ELT(PackElement)
197197

198-
/// Stores the generic environment for an opened pack element.
199-
CUSTOM_LOCATOR_PATH_ELT(OpenedPackElement)
200-
201198
/// The shape of a parameter pack.
202199
SIMPLE_LOCATOR_PATH_ELT(PackShape)
203200

include/swift/Sema/ConstraintSystem.h

+18-5
Original file line numberDiff line numberDiff line change
@@ -1494,6 +1494,10 @@ class Solution {
14941494
llvm::DenseMap<ConstraintLocator *, OpenedArchetypeType *>
14951495
OpenedExistentialTypes;
14961496

1497+
/// The pack expansion environment that can open pack elements for
1498+
/// a given locator.
1499+
llvm::DenseMap<ConstraintLocator *, UUID> PackExpansionEnvironments;
1500+
14971501
/// The locators of \c Defaultable constraints whose defaults were used.
14981502
llvm::SmallPtrSet<ConstraintLocator *, 2> DefaultedConstraints;
14991503

@@ -3021,6 +3025,8 @@ class ConstraintSystem {
30213025
llvm::SmallMapVector<ConstraintLocator *, OpenedArchetypeType *, 4>
30223026
OpenedExistentialTypes;
30233027

3028+
llvm::SmallMapVector<ConstraintLocator *, UUID, 4> PackExpansionEnvironments;
3029+
30243030
/// The set of functions that have been transformed by a result builder.
30253031
llvm::MapVector<AnyFunctionRef, AppliedBuilderTransform>
30263032
resultBuilderTransformed;
@@ -3496,6 +3502,9 @@ class ConstraintSystem {
34963502
/// The length of \c OpenedExistentialTypes.
34973503
unsigned numOpenedExistentialTypes;
34983504

3505+
/// The length of \c PackExpansionEnvironments.
3506+
unsigned numPackExpansionEnvironments;
3507+
34993508
/// The length of \c DefaultedConstraints.
35003509
unsigned numDefaultedConstraints;
35013510

@@ -3974,6 +3983,12 @@ class ConstraintSystem {
39743983
std::pair<Type, OpenedArchetypeType *> openExistentialType(
39753984
Type type, ConstraintLocator *locator);
39763985

3986+
/// Add the given pack expansion as an opened pack element environment.
3987+
void addPackElementEnvironment(PackExpansionExpr *expr);
3988+
3989+
/// Get the opened element generic environment for the given locator.
3990+
GenericEnvironment *getPackElementEnvironment(ConstraintLocator *locator);
3991+
39773992
/// Retrieve the constraint locator for the given anchor and
39783993
/// path, uniqued and automatically infer the summary flags
39793994
ConstraintLocator *
@@ -6124,12 +6139,12 @@ class HandlePlaceholderType {
61246139
class OpenPackElementType {
61256140
ConstraintSystem &cs;
61266141
ConstraintLocator *locator;
6127-
GenericEnvironment *elementEnv;
6142+
PackExpansionExpr *elementEnv;
61286143

61296144
public:
61306145
explicit OpenPackElementType(ConstraintSystem &cs,
61316146
const ConstraintLocatorBuilder &locator,
6132-
GenericEnvironment *elementEnv)
6147+
PackExpansionExpr *elementEnv)
61336148
: cs(cs), elementEnv(elementEnv) {
61346149
this->locator = cs.getConstraintLocator(locator);
61356150
}
@@ -6144,8 +6159,6 @@ class OpenPackElementType {
61446159
auto *elementType = cs.createTypeVariable(locator,
61456160
TVO_CanBindToHole |
61466161
TVO_CanBindToNoEscape);
6147-
auto elementLoc = cs.getConstraintLocator(locator,
6148-
LocatorPathElt::OpenedPackElement(elementEnv));
61496162

61506163
// If we're opening a pack element from an explicit type repr,
61516164
// set the type repr types in the constraint system for generating
@@ -6156,7 +6169,7 @@ class OpenPackElementType {
61566169
}
61576170

61586171
cs.addConstraint(ConstraintKind::PackElementOf, elementType,
6159-
packType, elementLoc);
6172+
packType, cs.getConstraintLocator(elementEnv));
61606173
return elementType;
61616174
}
61626175
};

lib/Sema/CSApply.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -3818,6 +3818,10 @@ namespace {
38183818
}
38193819

38203820
Expr *visitPackExpansionExpr(PackExpansionExpr *expr) {
3821+
auto *locator = cs.getConstraintLocator(expr);
3822+
auto *environment = cs.getPackElementEnvironment(locator);
3823+
expr->setGenericEnvironment(environment);
3824+
38213825
return simplifyExprType(expr);
38223826
}
38233827

lib/Sema/CSBindings.cpp

+1-5
Original file line numberDiff line numberDiff line change
@@ -1414,10 +1414,6 @@ void PotentialBindings::infer(Constraint *constraint) {
14141414
auto elementType = CS.simplifyType(constraint->getFirstType());
14151415
auto packType = CS.simplifyType(constraint->getSecondType());
14161416

1417-
auto *loc = constraint->getLocator();
1418-
auto openedElement =
1419-
loc->getLastElementAs<LocatorPathElt::OpenedPackElement>();
1420-
14211417
if (elementType->isTypeVariableOrMember() && packType->isTypeVariableOrMember())
14221418
break;
14231419

@@ -1428,7 +1424,7 @@ void PotentialBindings::infer(Constraint *constraint) {
14281424
// Produce a potential binding to the opened element archetype corresponding
14291425
// to the pack type.
14301426
packType = packType->mapTypeOutOfContext();
1431-
auto *elementEnv = openedElement->getGenericEnvironment();
1427+
auto *elementEnv = CS.getPackElementEnvironment(constraint->getLocator());
14321428
auto elementType = elementEnv->mapPackTypeIntoElementContext(packType);
14331429
addPotentialBinding({elementType, AllowedBindingKind::Exact, constraint});
14341430

lib/Sema/CSGen.cpp

+11-13
Original file line numberDiff line numberDiff line change
@@ -845,8 +845,8 @@ namespace {
845845
/// found during our walk.
846846
llvm::MapVector<UnresolvedMemberExpr *, Type> UnresolvedBaseTypes;
847847

848-
/// A stack of pack element generic environments.
849-
llvm::SmallVector<GenericEnvironment *, 2> PackElementEnvironments;
848+
/// A stack of pack expansions that can open pack elements.
849+
llvm::SmallVector<PackExpansionExpr *, 2> PackElementEnvironments;
850850

851851
/// Returns false and emits the specified diagnostic if the member reference
852852
/// base is a nil literal. Returns true otherwise.
@@ -1088,8 +1088,9 @@ namespace {
10881088

10891089
ConstraintSystem &getConstraintSystem() const { return CS; }
10901090

1091-
void addPackElementEnvironment(GenericEnvironment *env) {
1092-
PackElementEnvironments.push_back(env);
1091+
void addPackElementEnvironment(PackExpansionExpr *expr) {
1092+
CS.addPackElementEnvironment(expr);
1093+
PackElementEnvironments.push_back(expr);
10931094
}
10941095

10951096
virtual Type visitErrorExpr(ErrorExpr *E) {
@@ -1424,7 +1425,7 @@ namespace {
14241425
const auto placeholderHandler = HandlePlaceholderType(CS, locator);
14251426

14261427
// Add a PackElementOf constraint for 'each T' type reprs.
1427-
GenericEnvironment *elementEnv = nullptr;
1428+
PackExpansionExpr *elementEnv = nullptr;
14281429
if (!PackElementEnvironments.empty()) {
14291430
options |= TypeResolutionFlags::AllowPackReferences;
14301431
elementEnv = PackElementEnvironments.back();
@@ -1694,7 +1695,7 @@ namespace {
16941695
auto options =
16951696
TypeResolutionOptions(TypeResolverContext::InExpression);
16961697
for (auto specializationArg : specializationArgs) {
1697-
GenericEnvironment *elementEnv = nullptr;
1698+
PackExpansionExpr *elementEnv = nullptr;
16981699
if (!PackElementEnvironments.empty()) {
16991700
options |= TypeResolutionFlags::AllowPackReferences;
17001701
elementEnv = PackElementEnvironments.back();
@@ -1764,7 +1765,7 @@ namespace {
17641765
auto options =
17651766
TypeResolutionOptions(TypeResolverContext::InExpression);
17661767
for (size_t i = 0, e = specializations.size(); i < e; ++i) {
1767-
GenericEnvironment *elementEnv = nullptr;
1768+
PackExpansionExpr *elementEnv = nullptr;
17681769
if (!PackElementEnvironments.empty()) {
17691770
options |= TypeResolutionFlags::AllowPackReferences;
17701771
elementEnv = PackElementEnvironments.back();
@@ -3008,8 +3009,7 @@ namespace {
30083009
}
30093010

30103011
Type visitPackExpansionExpr(PackExpansionExpr *expr) {
3011-
auto *elementEnv = expr->getGenericEnvironment();
3012-
assert(PackElementEnvironments.back() == elementEnv);
3012+
assert(PackElementEnvironments.back() == expr);
30133013
PackElementEnvironments.pop_back();
30143014

30153015
auto *patternLoc =
@@ -3018,10 +3018,8 @@ namespace {
30183018
TVO_CanBindToPack |
30193019
TVO_CanBindToHole);
30203020
auto elementResultType = CS.getType(expr->getPatternExpr());
3021-
auto *elementLoc = CS.getConstraintLocator(
3022-
expr, LocatorPathElt::OpenedPackElement(elementEnv));
30233021
CS.addConstraint(ConstraintKind::PackElementOf, elementResultType,
3024-
patternTy, elementLoc);
3022+
patternTy, CS.getConstraintLocator(expr));
30253023

30263024
auto *shapeLoc =
30273025
CS.getConstraintLocator(expr, ConstraintLocator::PackShape);
@@ -4063,7 +4061,7 @@ namespace {
40634061
}
40644062

40654063
if (auto *expansion = dyn_cast<PackExpansionExpr>(expr)) {
4066-
CG.addPackElementEnvironment(expansion->getGenericEnvironment());
4064+
CG.addPackElementEnvironment(expansion);
40674065
}
40684066

40694067
return Action::Continue(expr);

lib/Sema/CSSolver.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,11 @@ void ConstraintSystem::applySolution(const Solution &solution) {
267267
OpenedExistentialTypes.insert(openedExistential);
268268
}
269269

270+
// Register the solutions's pack expansion environments.
271+
for (const auto &expansion : solution.PackExpansionEnvironments) {
272+
PackExpansionEnvironments.insert(expansion);
273+
}
274+
270275
// Register the defaulted type variables.
271276
DefaultedConstraints.insert(solution.DefaultedConstraints.begin(),
272277
solution.DefaultedConstraints.end());
@@ -585,6 +590,7 @@ ConstraintSystem::SolverScope::SolverScope(ConstraintSystem &cs)
585590
numArgumentMatchingChoices = cs.argumentMatchingChoices.size();
586591
numOpenedTypes = cs.OpenedTypes.size();
587592
numOpenedExistentialTypes = cs.OpenedExistentialTypes.size();
593+
numPackExpansionEnvironments = cs.PackExpansionEnvironments.size();
588594
numDefaultedConstraints = cs.DefaultedConstraints.size();
589595
numAddedNodeTypes = cs.addedNodeTypes.size();
590596
numAddedKeyPathComponentTypes = cs.addedKeyPathComponentTypes.size();
@@ -662,6 +668,9 @@ ConstraintSystem::SolverScope::~SolverScope() {
662668
// Remove any opened existential types.
663669
truncate(cs.OpenedExistentialTypes, numOpenedExistentialTypes);
664670

671+
// Remove any pack expansion environments.
672+
truncate(cs.PackExpansionEnvironments, numPackExpansionEnvironments);
673+
665674
// Remove any defaulted type variables.
666675
truncate(cs.DefaultedConstraints, numDefaultedConstraints);
667676

lib/Sema/ConstraintLocator.cpp

-6
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ unsigned LocatorPathElt::getNewSummaryFlags() const {
9797
case ConstraintLocator::SyntacticElement:
9898
case ConstraintLocator::PackType:
9999
case ConstraintLocator::PackElement:
100-
case ConstraintLocator::OpenedPackElement:
101100
case ConstraintLocator::PackShape:
102101
case ConstraintLocator::PackExpansionPattern:
103102
case ConstraintLocator::PatternBindingElement:
@@ -449,11 +448,6 @@ void LocatorPathElt::dump(raw_ostream &out) const {
449448
break;
450449
}
451450

452-
case ConstraintLocator::OpenedPackElement: {
453-
out << "opened pack element";
454-
break;
455-
}
456-
457451
case ConstraintLocator::PackShape: {
458452
out << "pack shape";
459453
break;

lib/Sema/ConstraintSystem.cpp

+20-1
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,26 @@ std::pair<Type, OpenedArchetypeType *> ConstraintSystem::openExistentialType(
637637
return {result, opened};
638638
}
639639

640+
void ConstraintSystem::addPackElementEnvironment(PackExpansionExpr *expr) {
641+
auto *locator = getConstraintLocator(expr);
642+
PackExpansionEnvironments[locator] = UUID::fromTime();
643+
}
644+
645+
GenericEnvironment *
646+
ConstraintSystem::getPackElementEnvironment(ConstraintLocator *locator) {
647+
auto result = PackExpansionEnvironments.find(locator);
648+
if (result == PackExpansionEnvironments.end())
649+
return nullptr;
650+
651+
auto uuid = result->second;
652+
auto &ctx = getASTContext();
653+
auto elementSig = ctx.getOpenedElementSignature(
654+
DC->getGenericSignatureOfContext().getCanonicalSignature());
655+
auto *contextEnv = DC->getGenericEnvironmentOfContext();
656+
auto contextSubs = contextEnv->getForwardingSubstitutionMap();
657+
return GenericEnvironment::forOpenedElement(elementSig, uuid, contextSubs);
658+
}
659+
640660
/// Extend the given depth map by adding depths for all of the subexpressions
641661
/// of the given expression.
642662
static void extendDepthMap(
@@ -5378,7 +5398,6 @@ void constraints::simplifyLocator(ASTNode &anchor,
53785398
break;
53795399

53805400
case ConstraintLocator::PackElement:
5381-
case ConstraintLocator::OpenedPackElement:
53825401
case ConstraintLocator::PackShape:
53835402
break;
53845403

lib/Sema/PreCheckExpr.cpp

-21
Original file line numberDiff line numberDiff line change
@@ -399,21 +399,6 @@ static BinaryExpr *getCompositionExpr(Expr *expr) {
399399
return nullptr;
400400
}
401401

402-
static void
403-
setPackElementEnvironment(DeclContext *dc, PackExpansionExpr *expansion) {
404-
// FIXME: The generic environment should be created lazily when solving
405-
// PackElementOf constraints.
406-
auto &ctx = dc->getASTContext();
407-
auto sig = ctx.getOpenedElementSignature(
408-
dc->getGenericSignatureOfContext().getCanonicalSignature());
409-
auto *contextEnv = dc->getGenericEnvironmentOfContext();
410-
auto contextSubs = contextEnv->getForwardingSubstitutionMap();
411-
auto *environment =
412-
GenericEnvironment::forOpenedElement(sig, UUID::fromTime(),
413-
contextSubs);
414-
expansion->setGenericEnvironment(environment);
415-
}
416-
417402
/// Bind an UnresolvedDeclRefExpr by performing name lookup and
418403
/// returning the resultant expression. Context is the DeclContext used
419404
/// for the lookup.
@@ -1160,12 +1145,6 @@ namespace {
11601145
return Action::Continue(result);
11611146
}
11621147

1163-
// Set the generic environment of a PackExpansionExpr.
1164-
if (auto *expansion = dyn_cast<PackExpansionExpr>(expr)) {
1165-
setPackElementEnvironment(DC, expansion);
1166-
return Action::Continue(expansion);
1167-
}
1168-
11691148
// Type check the type parameters in an UnresolvedSpecializeExpr.
11701149
if (auto *us = dyn_cast<UnresolvedSpecializeExpr>(expr)) {
11711150
if (auto *typeExpr = simplifyUnresolvedSpecializeExpr(us))

0 commit comments

Comments
 (0)