Skip to content

Commit 751edee

Browse files
committed
Sema: Rework PreparedOverload to store a list of changes
1 parent 2a0b11a commit 751edee

File tree

7 files changed

+191
-55
lines changed

7 files changed

+191
-55
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4438,7 +4438,8 @@ class ConstraintSystem {
44384438

44394439
/// Update OpenedTypes and record a change in the trail.
44404440
void recordOpenedType(
4441-
ConstraintLocator *locator, ArrayRef<OpenedType> openedTypes);
4441+
ConstraintLocator *locator, ArrayRef<OpenedType> openedTypes,
4442+
PreparedOverload *preparedOverload = nullptr);
44424443

44434444
/// Record the set of opened types for the given locator.
44444445
void recordOpenedTypes(

include/swift/Sema/PreparedOverload.h

Lines changed: 123 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,130 @@ class ConstraintSystem;
3131
/// variable.
3232
using OpenedType = std::pair<GenericTypeParamType *, TypeVariableType *>;
3333

34+
/// A "pre-cooked" representation of all type variables and constraints
35+
/// that are generated as part of an overload choice.
3436
struct PreparedOverload {
35-
SmallVector<TypeVariableType *, 2> TypeVariables;
36-
SmallVector<Constraint *, 2> Constraints;
37-
SmallVector<OpenedType, 2> Replacements;
38-
ExistentialArchetypeType *OpenedExistential = nullptr;
39-
SmallVector<std::pair<PackExpansionType *, TypeVariableType *>>
40-
OpenedPackExpansionTypes;
41-
SmallVector<AppliedPropertyWrapper, 2> PropertyWrappers;
42-
SmallVector<std::pair<ConstraintFix *, unsigned>, 2> Fixes;
37+
/// A change to be introduced into the constraint system when this
38+
/// overload choice is chosen.
39+
struct Change {
40+
enum ChangeKind : unsigned {
41+
/// A generic parameter was opened to a type variable.
42+
AddedTypeVariable,
43+
44+
/// A generic requirement was opened to a constraint.
45+
AddedConstraint,
46+
47+
/// A mapping of generic parameter types to type variables
48+
/// was recorded.
49+
OpenedTypes,
50+
51+
/// An existential type was opened.
52+
OpenedExistentialType,
53+
54+
/// A pack expansion type was opened.
55+
OpenedPackExpansionType,
56+
57+
/// A property wrapper was applied to a parameter.
58+
AppliedPropertyWrapper,
59+
60+
/// A fix was recorded because a property wrapper application failed.
61+
AddedFix
62+
};
63+
64+
/// The kind of change.
65+
ChangeKind Kind;
66+
67+
union {
68+
/// For ChangeKind::AddedTypeVariable.
69+
TypeVariableType *TypeVar;
70+
71+
/// For ChangeKind::AddedConstraint.
72+
Constraint *TheConstraint;
73+
74+
/// For ChangeKind::OpenedTypes.
75+
struct {
76+
const OpenedType *Data;
77+
size_t Count;
78+
} Replacements;
79+
80+
/// For ChangeKind::OpenedExistentialType.
81+
ExistentialArchetypeType *TheExistential;
82+
83+
/// For ChangeKind::OpenedPackExpansionType.
84+
struct {
85+
PackExpansionType *TheExpansion;
86+
TypeVariableType *TypeVar;
87+
} PackExpansion;
88+
89+
/// For ChangeKind::AppliedPropertyWrapper.
90+
struct {
91+
TypeBase *WrapperType;
92+
PropertyWrapperInitKind InitKind;
93+
} PropertyWrapper;
94+
95+
/// For ChangeKind::Fix.
96+
struct {
97+
ConstraintFix *TheFix;
98+
unsigned Impact;
99+
} Fix;
100+
};
101+
};
102+
103+
SmallVector<Change, 8> Changes;
104+
105+
void addedTypeVariable(TypeVariableType *typeVar) {
106+
Change change;
107+
change.Kind = Change::AddedTypeVariable;
108+
change.TypeVar = typeVar;
109+
Changes.push_back(change);
110+
}
111+
112+
void addedConstraint(Constraint *constraint) {
113+
Change change;
114+
change.Kind = Change::AddedConstraint;
115+
change.TheConstraint = constraint;
116+
Changes.push_back(change);
117+
}
118+
119+
void openedTypes(ArrayRef<OpenedType> replacements) {
120+
Change change;
121+
change.Kind = Change::OpenedTypes;
122+
change.Replacements.Data = replacements.data();
123+
change.Replacements.Count = replacements.size();
124+
Changes.push_back(change);
125+
}
126+
127+
void openedExistentialType(ExistentialArchetypeType *openedExistential) {
128+
Change change;
129+
change.Kind = Change::OpenedExistentialType;
130+
change.TheExistential = openedExistential;
131+
Changes.push_back(change);
132+
}
133+
134+
void openedPackExpansionType(PackExpansionType *packExpansion,
135+
TypeVariableType *typeVar) {
136+
Change change;
137+
change.Kind = Change::OpenedPackExpansionType;
138+
change.PackExpansion.TheExpansion = packExpansion;
139+
change.PackExpansion.TypeVar = typeVar;
140+
Changes.push_back(change);
141+
}
142+
143+
void appliedPropertyWrapper(AppliedPropertyWrapper wrapper) {
144+
Change change;
145+
change.Kind = Change::AppliedPropertyWrapper;
146+
change.PropertyWrapper.WrapperType = wrapper.wrapperType.getPointer();
147+
change.PropertyWrapper.InitKind = wrapper.initKind;
148+
Changes.push_back(change);
149+
}
150+
151+
void addedFix(ConstraintFix *fix, unsigned impact) {
152+
Change change;
153+
change.Kind = Change::AddedFix;
154+
change.Fix.TheFix = fix;
155+
change.Fix.Impact = impact;
156+
Changes.push_back(change);
157+
}
43158

44159
void discharge(ConstraintSystem &cs, ConstraintLocatorBuilder locator) const;
45160
};

lib/Sema/CSGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5122,7 +5122,7 @@ void ConstraintSystem::applyPropertyWrapper(
51225122
PreparedOverload *preparedOverload) {
51235123
if (preparedOverload) {
51245124
ASSERT(PreparingOverload);
5125-
preparedOverload->PropertyWrappers.push_back(applied);
5125+
preparedOverload->appliedPropertyWrapper(applied);
51265126
return;
51275127
}
51285128

lib/Sema/CSSimplify.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15407,7 +15407,7 @@ bool ConstraintSystem::recordFix(ConstraintFix *fix, unsigned impact,
1540715407
PreparedOverload *preparedOverload) {
1540815408
if (preparedOverload) {
1540915409
ASSERT(PreparingOverload);
15410-
preparedOverload->Fixes.push_back({fix, impact});
15410+
preparedOverload->addedFix(fix, impact);
1541115411
return true;
1541215412
}
1541315413

@@ -16350,7 +16350,7 @@ void ConstraintSystem::addConstraint(ConstraintKind kind, Type first,
1635016350
auto c = Constraint::create(*this, kind, first, second,
1635116351
getConstraintLocator(locator));
1635216352
if (isFavored) c->setFavored();
16353-
preparedOverload->Constraints.push_back(c);
16353+
preparedOverload->addedConstraint(c);
1635416354
return;
1635516355
}
1635616356

lib/Sema/CSSolver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ TypeVariableType *ConstraintSystem::createTypeVariable(
6666
locator, options);
6767
if (preparedOverload) {
6868
ASSERT(PreparingOverload);
69-
preparedOverload->TypeVariables.push_back(tv);
69+
preparedOverload->addedTypeVariable(tv);
7070
} else {
7171
addTypeVariable(tv);
7272
}

lib/Sema/ConstraintSystem.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -906,8 +906,7 @@ void ConstraintSystem::recordOpenedExistentialType(
906906
ExistentialArchetypeType *opened,
907907
PreparedOverload *preparedOverload) {
908908
if (preparedOverload) {
909-
ASSERT(!preparedOverload->OpenedExistential);
910-
preparedOverload->OpenedExistential = opened;
909+
preparedOverload->openedExistentialType(opened);
911910
return;
912911
}
913912

lib/Sema/TypeOfReference.cpp

Lines changed: 61 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -321,9 +321,10 @@ Type ConstraintSystem::openPackExpansionType(PackExpansionType *expansion,
321321
// "opening" pack expansions is broken.
322322
{
323323
if (preparedOverload) {
324-
for (auto pair : preparedOverload->OpenedPackExpansionTypes) {
325-
if (pair.first == openedPackExpansion)
326-
return pair.second;
324+
for (auto change : preparedOverload->Changes) {
325+
if (change.Kind == PreparedOverload::Change::OpenedPackExpansionType &&
326+
change.PackExpansion.TheExpansion == openedPackExpansion)
327+
return change.PackExpansion.TypeVar;
327328
}
328329
}
329330

@@ -345,7 +346,7 @@ Type ConstraintSystem::openPackExpansionType(PackExpansionType *expansion,
345346
expansionVar, openedPackExpansion,
346347
expansionLoc);
347348
if (preparedOverload)
348-
preparedOverload->Constraints.push_back(c);
349+
preparedOverload->addedConstraint(c);
349350
else
350351
addUnsolvedConstraint(c);
351352

@@ -359,7 +360,7 @@ void ConstraintSystem::recordOpenedPackExpansionType(PackExpansionType *expansio
359360
PreparedOverload *preparedOverload) {
360361
if (preparedOverload) {
361362
ASSERT(PreparingOverload);
362-
preparedOverload->OpenedPackExpansionTypes.push_back({expansion, expansionVar});
363+
preparedOverload->openedPackExpansionType(expansion, expansionVar);
363364
return;
364365
}
365366

@@ -699,8 +700,17 @@ Type ConstraintSystem::getUnopenedTypeOfReference(
699700
}
700701

701702
void ConstraintSystem::recordOpenedType(
702-
ConstraintLocator *locator, ArrayRef<OpenedType> openedTypes) {
703-
bool inserted = OpenedTypes.insert({locator, openedTypes}).second;
703+
ConstraintLocator *locator, ArrayRef<OpenedType> replacements,
704+
PreparedOverload *preparedOverload) {
705+
if (preparedOverload) {
706+
ASSERT(PreparingOverload);
707+
preparedOverload->openedTypes(replacements);
708+
return;
709+
}
710+
711+
ASSERT(!PreparingOverload);
712+
713+
bool inserted = OpenedTypes.insert({locator, replacements}).second;
704714
ASSERT(inserted);
705715

706716
if (solverState)
@@ -715,16 +725,6 @@ void ConstraintSystem::recordOpenedTypes(
715725
if (replacements.empty())
716726
return;
717727

718-
if (preparedOverload) {
719-
ASSERT(PreparingOverload);
720-
ASSERT(preparedOverload->Replacements.empty());
721-
preparedOverload->Replacements.append(
722-
replacements.begin(), replacements.end());
723-
return;
724-
}
725-
726-
ASSERT(!PreparingOverload);
727-
728728
// If the last path element is an archetype or associated type, ignore it.
729729
SmallVector<LocatorPathElt, 2> pathElts;
730730
auto anchor = locator.getLocatorParts(pathElts);
@@ -746,7 +746,8 @@ void ConstraintSystem::recordOpenedTypes(
746746
// FIXME: Get rid of fixmeAllowDuplicates.
747747
if (!fixmeAllowDuplicates || OpenedTypes.count(locatorPtr) == 0)
748748
recordOpenedType(
749-
locatorPtr, llvm::ArrayRef(openedTypes, replacements.size()));
749+
locatorPtr, llvm::ArrayRef(openedTypes, replacements.size()),
750+
preparedOverload);
750751
}
751752

752753
/// Determine how many levels of argument labels should be removed from the
@@ -2496,35 +2497,55 @@ void ConstraintSystem::recordResolvedOverload(ConstraintLocator *locator,
24962497

24972498
void PreparedOverload::discharge(ConstraintSystem &cs,
24982499
ConstraintLocatorBuilder locator) const {
2499-
for (auto *tv : TypeVariables) {
2500-
cs.addTypeVariable(tv);
2501-
}
2500+
for (auto change : Changes) {
2501+
switch (change.Kind) {
2502+
case PreparedOverload::Change::AddedTypeVariable:
2503+
cs.addTypeVariable(change.TypeVar);
2504+
break;
25022505

2503-
for (auto *c : Constraints) {
2504-
cs.addUnsolvedConstraint(c);
2505-
cs.activateConstraint(c);
2506-
}
2506+
case PreparedOverload::Change::AddedConstraint:
2507+
cs.addUnsolvedConstraint(change.TheConstraint);
2508+
cs.activateConstraint(change.TheConstraint);
2509+
break;
25072510

2508-
cs.recordOpenedTypes(locator, Replacements);
2511+
case PreparedOverload::Change::OpenedTypes: {
2512+
auto *locatorPtr = cs.getConstraintLocator(locator);
2513+
ArrayRef<OpenedType> replacements(
2514+
change.Replacements.Data,
2515+
change.Replacements.Count);
25092516

2510-
if (OpenedExistential) {
2511-
cs.recordOpenedExistentialType(cs.getConstraintLocator(locator),
2512-
OpenedExistential);
2513-
}
2517+
// FIXME: Get rid of this conditional.
2518+
if (cs.getOpenedTypes(locatorPtr).empty())
2519+
cs.recordOpenedType(locatorPtr, replacements);
2520+
break;
2521+
}
25142522

2515-
for (auto pair : OpenedPackExpansionTypes) {
2516-
cs.recordOpenedPackExpansionType(pair.first, pair.second);
2517-
}
2523+
case PreparedOverload::Change::OpenedExistentialType: {
2524+
auto *locatorPtr = cs.getConstraintLocator(locator);
2525+
cs.recordOpenedExistentialType(locatorPtr,
2526+
change.TheExistential);
2527+
break;
2528+
}
2529+
2530+
case PreparedOverload::Change::OpenedPackExpansionType:
2531+
cs.recordOpenedPackExpansionType(
2532+
change.PackExpansion.TheExpansion,
2533+
change.PackExpansion.TypeVar);
2534+
break;
25182535

2519-
if (!PropertyWrappers.empty()) {
2520-
Expr *anchor = getAsExpr(cs.getConstraintLocator(locator)->getAnchor());
2521-
for (auto applied : PropertyWrappers) {
2522-
cs.applyPropertyWrapper(anchor, applied);
2536+
case PreparedOverload::Change::AppliedPropertyWrapper: {
2537+
auto *locatorPtr = cs.getConstraintLocator(locator);
2538+
Expr *anchor = getAsExpr(locatorPtr->getAnchor());
2539+
cs.applyPropertyWrapper(anchor,
2540+
{ Type(change.PropertyWrapper.WrapperType),
2541+
change.PropertyWrapper.InitKind });
2542+
break;
25232543
}
2524-
}
25252544

2526-
for (auto pair : Fixes) {
2527-
cs.recordFix(pair.first, pair.second);
2545+
case PreparedOverload::Change::AddedFix:
2546+
cs.recordFix(change.Fix.TheFix, change.Fix.Impact);
2547+
break;
2548+
}
25282549
}
25292550
}
25302551

0 commit comments

Comments
 (0)