Skip to content

Commit 49487b8

Browse files
committed
Sema: Record fixed requirements in the trail
1 parent df692ed commit 49487b8

File tree

5 files changed

+86
-11
lines changed

5 files changed

+86
-11
lines changed

include/swift/Sema/CSTrail.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ class SolverTrail {
5757
AddedConversionRestriction,
5858
/// Recorded a fix.
5959
AddedFix,
60+
/// Recorded a fixed requirement.
61+
AddedFixedRequirement,
6062
};
6163

6264
/// A change made to the constraint system.
@@ -115,6 +117,11 @@ class SolverTrail {
115117
} Restriction;
116118

117119
ConstraintFix *Fix;
120+
121+
struct {
122+
GenericTypeParamType *GP;
123+
Type ReqTy;
124+
} FixedRequirement;
118125
};
119126

120127
Change() : Kind(ChangeKind::AddedTypeVariable), TypeVar(nullptr) { }
@@ -157,6 +164,11 @@ class SolverTrail {
157164
/// Create a change that recorded a fix.
158165
static Change addedFix(ConstraintFix *fix);
159166

167+
/// Create a change that recorded a fixed requirement.
168+
static Change addedFixedRequirement(GenericTypeParamType *GP,
169+
unsigned reqKind,
170+
Type requirementTy);
171+
160172
/// Undo this change, reverting the constraint graph to the state it
161173
/// had prior to this change.
162174
///

include/swift/Sema/ConstraintSystem.h

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1507,6 +1507,11 @@ class Solution {
15071507
/// to make the solution work.
15081508
std::vector<ConstraintFix *> Fixes;
15091509

1510+
/// The list of fixed requirements.
1511+
using FixedRequirement =
1512+
std::tuple<GenericTypeParamType *, unsigned, TypeBase *>;
1513+
std::vector<FixedRequirement> FixedRequirements;
1514+
15101515
/// Maps expressions for implied results (e.g implicit 'then' statements,
15111516
/// implicit 'return' statements in single expression body closures) to their
15121517
/// result kind.
@@ -2138,6 +2143,7 @@ class ConstraintSystem {
21382143
friend class RequirementFailure;
21392144
friend class MissingMemberFailure;
21402145
friend struct ClosureIsolatedByPreconcurrency;
2146+
friend class SolverTrail;
21412147

21422148
class SolverScope;
21432149

@@ -2363,12 +2369,22 @@ class ConstraintSystem {
23632369
/// solver path.
23642370
using FixedRequirement =
23652371
std::tuple<GenericTypeParamType *, unsigned, TypeBase *>;
2366-
llvm::SmallSetVector<FixedRequirement, 4> FixedRequirements;
2372+
llvm::DenseSet<FixedRequirement> FixedRequirements;
23672373

23682374
bool isFixedRequirement(ConstraintLocator *reqLocator, Type requirementTy);
2375+
2376+
/// Add a fixed requirement and record a change to the trail.
23692377
void recordFixedRequirement(ConstraintLocator *reqLocator,
23702378
Type requirementTy);
23712379

2380+
/// Primitive form used when applying solution.
2381+
void recordFixedRequirement(GenericTypeParamType *paramTy,
2382+
unsigned reqKind, Type reqTy);
2383+
2384+
/// Called to undo the above change.
2385+
void removeFixedRequirement(GenericTypeParamType *paramTy,
2386+
unsigned reqKind, Type reqTy);
2387+
23722388
/// A mapping from constraint locators to the opened existential archetype
23732389
/// used for the 'self' of an existential type.
23742390
llvm::SmallMapVector<ConstraintLocator *, OpenedArchetypeType *, 4>
@@ -2863,9 +2879,6 @@ class ConstraintSystem {
28632879
/// FIXME: Remove this.
28642880
unsigned numFixes;
28652881

2866-
/// The length of \c FixedRequirements.
2867-
unsigned numFixedRequirements;
2868-
28692882
/// The length of \c DisjunctionChoices.
28702883
unsigned numDisjunctionChoices;
28712884

lib/Sema/CSSolver.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ Solution ConstraintSystem::finalize() {
137137
llvm::make_range(Fixes.begin() + firstFixIndex, Fixes.end()))
138138
solution.Fixes.push_back(fix);
139139

140+
for (const auto &fix : FixedRequirements) {
141+
solution.FixedRequirements.push_back(fix);
142+
}
143+
140144
// Remember all the disjunction choices we made.
141145
for (auto &choice : DisjunctionChoices) {
142146
solution.DisjunctionChoices.insert(choice);
@@ -421,6 +425,10 @@ void ConstraintSystem::applySolution(const Solution &solution) {
421425
// Register any fixes produced along this path.
422426
for (auto *fix : solution.Fixes)
423427
addFix(fix);
428+
429+
// Register fixed requirements.
430+
for (auto fix : solution.FixedRequirements)
431+
recordFixedRequirement(std::get<0>(fix), std::get<1>(fix), std::get<2>(fix));
424432
}
425433
bool ConstraintSystem::simplify() {
426434
// While we have a constraint in the worklist, process it.
@@ -654,7 +662,6 @@ ConstraintSystem::SolverScope::SolverScope(ConstraintSystem &cs)
654662

655663
numTypeVariables = cs.TypeVariables.size();
656664
numFixes = cs.Fixes.size();
657-
numFixedRequirements = cs.FixedRequirements.size();
658665
numDisjunctionChoices = cs.DisjunctionChoices.size();
659666
numAppliedDisjunctions = cs.AppliedDisjunctions.size();
660667
numArgumentMatchingChoices = cs.argumentMatchingChoices.size();
@@ -732,10 +739,6 @@ ConstraintSystem::SolverScope::~SolverScope() {
732739
// Remove any opened types.
733740
truncate(cs.OpenedTypes, numOpenedTypes);
734741

735-
// Remove any conformances solver had to fix along
736-
// the current path.
737-
truncate(cs.FixedRequirements, numFixedRequirements);
738-
739742
// Remove any opened existential types.
740743
truncate(cs.OpenedExistentialTypes, numOpenedExistentialTypes);
741744

lib/Sema/CSTrail.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,18 @@ SolverTrail::Change::addedFix(ConstraintFix *fix) {
139139
return result;
140140
}
141141

142+
SolverTrail::Change
143+
SolverTrail::Change::addedFixedRequirement(GenericTypeParamType *GP,
144+
unsigned reqKind,
145+
Type reqTy) {
146+
Change result;
147+
result.Kind = ChangeKind::AddedFixedRequirement;
148+
result.FixedRequirement.GP = GP;
149+
result.FixedRequirement.ReqTy = reqTy;
150+
result.Options = reqKind;
151+
return result;
152+
}
153+
142154
void SolverTrail::Change::undo(ConstraintSystem &cs) const {
143155
auto &cg = cs.getConstraintGraph();
144156

@@ -186,6 +198,11 @@ void SolverTrail::Change::undo(ConstraintSystem &cs) const {
186198
case ChangeKind::AddedFix:
187199
cs.removeFix(Fix);
188200
break;
201+
202+
case ChangeKind::AddedFixedRequirement:
203+
cs.removeFixedRequirement(FixedRequirement.GP, Options,
204+
FixedRequirement.ReqTy);
205+
break;
189206
}
190207
}
191208

@@ -287,6 +304,15 @@ void SolverTrail::Change::dump(llvm::raw_ostream &out,
287304
Fix->print(out);
288305
out << ")\n";
289306
break;
307+
308+
case ChangeKind::AddedFixedRequirement:
309+
out << "(added a fixed requirement ";
310+
FixedRequirement.GP->print(out, PO);
311+
out << " kind ";
312+
out << Options << " ";
313+
FixedRequirement.ReqTy->print(out, PO);
314+
out << ")\n";
315+
break;
290316
}
291317
}
292318

lib/Sema/ConstraintSystem.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4404,6 +4404,7 @@ size_t Solution::getTotalMemory() const {
44044404
overloadChoices.getMemorySize() +
44054405
ConstraintRestrictions.getMemorySize() +
44064406
(Fixes.size() * sizeof(void *)) + DisjunctionChoices.getMemorySize() +
4407+
AppliedDisjunctions.getMemorySize() +
44074408
OpenedTypes.getMemorySize() + OpenedExistentialTypes.getMemorySize() +
44084409
OpenedPackExpansionTypes.getMemorySize() +
44094410
PackExpansionEnvironments.getMemorySize() +
@@ -7369,11 +7370,31 @@ void ConstraintSystem::recordFixedRequirement(ConstraintLocator *reqLocator,
73697370
if (auto reqInfo = getRequirementInfo(*this, reqLocator)) {
73707371
auto *GP = reqInfo->first;
73717372
auto reqKind = static_cast<unsigned>(reqInfo->second);
7372-
FixedRequirements.insert(
7373-
std::make_tuple(GP, reqKind, requirementTy.getPointer()));
7373+
recordFixedRequirement(GP, reqKind, requirementTy);
7374+
}
7375+
}
7376+
7377+
void ConstraintSystem::recordFixedRequirement(GenericTypeParamType *GP,
7378+
unsigned reqKind,
7379+
Type requirementTy) {
7380+
bool inserted = FixedRequirements.insert(
7381+
std::make_tuple(GP, reqKind, requirementTy.getPointer())).second;
7382+
if (inserted) {
7383+
if (isRecordingChanges()) {
7384+
recordChange(SolverTrail::Change::addedFixedRequirement(
7385+
GP, reqKind, requirementTy));
7386+
}
73747387
}
73757388
}
73767389

7390+
void ConstraintSystem::removeFixedRequirement(GenericTypeParamType *GP,
7391+
unsigned reqKind,
7392+
Type requirementTy) {
7393+
auto key = std::make_tuple(GP, reqKind, requirementTy.getPointer());
7394+
bool erased = FixedRequirements.erase(key);
7395+
ASSERT(erased);
7396+
}
7397+
73777398
// Replace any error types encountered with placeholders.
73787399
Type ConstraintSystem::getVarType(const VarDecl *var) {
73797400
auto type = var->getTypeInContext();

0 commit comments

Comments
 (0)