Skip to content

Commit 62a470e

Browse files
committed
Sema: Record conversion restrictions in the trail
1 parent 31edb86 commit 62a470e

File tree

6 files changed

+78
-21
lines changed

6 files changed

+78
-21
lines changed

include/swift/Sema/CSTrail.h

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class SolverTrail {
3636
public:
3737

3838
/// The kind of change made to the graph.
39-
enum class ChangeKind {
39+
enum class ChangeKind: unsigned {
4040
/// Added a new vertex to the constraint graph.
4141
AddedTypeVariable,
4242
/// Added a new constraint to the constraint graph.
@@ -53,6 +53,8 @@ class SolverTrail {
5353
RetractedBindings,
5454
/// Set the fixed type or parent and flags for a type variable.
5555
UpdatedTypeVariable,
56+
/// Recorded a conversion restriction kind.
57+
AddedConversionRestriction,
5658
};
5759

5860
/// A change made to the constraint system.
@@ -64,6 +66,9 @@ class SolverTrail {
6466
/// The kind of change.
6567
ChangeKind Kind;
6668

69+
/// Extra storage.
70+
unsigned Options;
71+
6772
union {
6873
TypeVariableType *TypeVar;
6974

@@ -97,10 +102,15 @@ class SolverTrail {
97102

98103
/// The representative of the equivalence class, or the fixed type.
99104
llvm::PointerUnion<TypeVariableType *, TypeBase *> ParentOrFixed;
100-
101-
/// The saved value of TypeVariableType::Implementation::getRawOptions().
102-
unsigned Options;
103105
} Update;
106+
107+
struct {
108+
/// The source type.
109+
Type SrcType;
110+
111+
/// The destination type.
112+
Type DstType;
113+
} Restriction;
104114
};
105115

106116
Change() : Kind(ChangeKind::AddedTypeVariable), TypeVar(nullptr) { }
@@ -137,6 +147,9 @@ class SolverTrail {
137147
llvm::PointerUnion<TypeVariableType *, TypeBase *> parentOrFixed,
138148
unsigned options);
139149

150+
/// Create a change that recorded a restriction.
151+
static Change addedConversionRestriction(Type srcType, Type dstType);
152+
140153
/// Undo this change, reverting the constraint graph to the state it
141154
/// had prior to this change.
142155
///

include/swift/Sema/ConstraintSystem.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2314,7 +2314,7 @@ class ConstraintSystem {
23142314
/// there are multiple ways in which one type could convert to another, e.g.,
23152315
/// given class types A and B, the solver might choose either a superclass
23162316
/// conversion or a user-defined conversion.
2317-
llvm::MapVector<std::pair<TypeBase *, TypeBase *>, ConversionRestrictionKind>
2317+
llvm::DenseMap<std::pair<TypeBase *, TypeBase *>, ConversionRestrictionKind>
23182318
ConstraintRestrictions;
23192319

23202320
/// The set of fixes applied to make the solution work.
@@ -2858,9 +2858,6 @@ class ConstraintSystem {
28582858
/// The length of \c Trail.
28592859
unsigned numTrailChanges;
28602860

2861-
/// The length of \c ConstraintRestrictions.
2862-
unsigned numConstraintRestrictions;
2863-
28642861
/// The length of \c Fixes.
28652862
unsigned numFixes;
28662863

@@ -4218,6 +4215,13 @@ class ConstraintSystem {
42184215
bool updateState = true,
42194216
bool notifyBindingInference = true);
42204217

4218+
/// Update ConstraintRestrictions and record a change in the trail.
4219+
void addConversionRestriction(Type srcType, Type dstType,
4220+
ConversionRestrictionKind restriction);
4221+
4222+
/// Called to undo the above change.
4223+
void removeConversionRestriction(Type srcType, Type dstType);
4224+
42214225
/// Determine whether the given type is a dictionary and, if so, provide the
42224226
/// key and value types for the dictionary.
42234227
static std::optional<std::pair<Type, Type>> isDictionaryType(Type type);

lib/Sema/CSSimplify.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14676,8 +14676,7 @@ ConstraintSystem::simplifyRestrictedConstraint(
1467614676
addFixConstraint(fix, matchKind, type1, type2, locator);
1467714677
}
1467814678

14679-
ConstraintRestrictions.insert({
14680-
std::make_pair(type1.getPointer(), type2.getPointer()), restriction});
14679+
addConversionRestriction(type1, type2, restriction);
1468114680
return SolutionKind::Solved;
1468214681
}
1468314682
case SolutionKind::Unsolved:

lib/Sema/CSSolver.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -290,10 +290,10 @@ void ConstraintSystem::applySolution(const Solution &solution) {
290290
// Register constraint restrictions.
291291
// FIXME: Copy these directly into some kind of partial solution?
292292
for ( auto &restriction : solution.ConstraintRestrictions) {
293-
auto *type1 = restriction.first.first.getPointer();
294-
auto *type2 = restriction.first.second.getPointer();
293+
auto type1 = restriction.first.first;
294+
auto type2 = restriction.first.second;
295295

296-
ConstraintRestrictions.insert({{type1, type2}, restriction.second});
296+
addConversionRestriction(type1, type2, restriction.second);
297297
}
298298

299299
// Register the solution's disjunction choices.
@@ -652,7 +652,6 @@ ConstraintSystem::SolverScope::SolverScope(ConstraintSystem &cs)
652652
numTrailChanges = cs.solverState->Trail.size();
653653

654654
numTypeVariables = cs.TypeVariables.size();
655-
numConstraintRestrictions = cs.ConstraintRestrictions.size();
656655
numFixes = cs.Fixes.size();
657656
numFixedRequirements = cs.FixedRequirements.size();
658657
numDisjunctionChoices = cs.DisjunctionChoices.size();
@@ -720,9 +719,6 @@ ConstraintSystem::SolverScope::~SolverScope() {
720719
// constraints introduced by the current scope.
721720
cs.solverState->rollback(this);
722721

723-
// Remove any constraint restrictions.
724-
truncate(cs.ConstraintRestrictions, numConstraintRestrictions);
725-
726722
// Remove any fixes.
727723
truncate(cs.Fixes, numFixes);
728724

lib/Sema/CSTrail.cpp

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,16 @@ SolverTrail::Change::updatedTypeVariable(
118118
result.Kind = ChangeKind::UpdatedTypeVariable;
119119
result.Update.TypeVar = typeVar;
120120
result.Update.ParentOrFixed = parentOrFixed;
121-
result.Update.Options = options;
121+
result.Options = options;
122+
return result;
123+
}
124+
125+
SolverTrail::Change
126+
SolverTrail::Change::addedConversionRestriction(Type srcType, Type dstType) {
127+
Change result;
128+
result.Kind = ChangeKind::AddedConversionRestriction;
129+
result.Restriction.SrcType = srcType;
130+
result.Restriction.DstType = dstType;
122131
return result;
123132
}
124133

@@ -157,9 +166,14 @@ void SolverTrail::Change::undo(ConstraintSystem &cs) const {
157166
break;
158167

159168
case ChangeKind::UpdatedTypeVariable:
160-
Update.TypeVar->getImpl().setRawOptions(Update.Options);
169+
Update.TypeVar->getImpl().setRawOptions(Options);
161170
Update.TypeVar->getImpl().ParentOrFixed = Update.ParentOrFixed;
162171
break;
172+
173+
case ChangeKind::AddedConversionRestriction:
174+
cs.removeConversionRestriction(Restriction.SrcType,
175+
Restriction.DstType);
176+
break;
163177
}
164178
}
165179

@@ -229,7 +243,7 @@ void SolverTrail::Change::dump(llvm::raw_ostream &out,
229243
out << ")\n";
230244
break;
231245

232-
case ChangeKind::UpdatedTypeVariable:
246+
case ChangeKind::UpdatedTypeVariable: {
233247
out << "(updated type variable ";
234248
Update.TypeVar->print(out, PO);
235249

@@ -243,7 +257,16 @@ void SolverTrail::Change::dump(llvm::raw_ostream &out,
243257
parentOrFixed.get<TypeBase *>()->print(out, PO);
244258
}
245259
out << " with options 0x";
246-
out.write_hex(Update.Options);
260+
out.write_hex(Options);
261+
out << ")\n";
262+
break;
263+
}
264+
265+
case ChangeKind::AddedConversionRestriction:
266+
out << "(added restriction with source ";
267+
Restriction.SrcType->print(out, PO);
268+
out << " and destination ";
269+
Restriction.DstType->print(out, PO);
247270
out << ")\n";
248271
break;
249272
}

lib/Sema/ConstraintSystem.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,28 @@ void ConstraintSystem::addTypeVariableConstraintsToWorkList(
257257
activateConstraint(constraint);
258258
}
259259

260+
void ConstraintSystem::addConversionRestriction(
261+
Type srcType, Type dstType,
262+
ConversionRestrictionKind restriction) {
263+
auto key = std::make_pair(srcType.getPointer(), dstType.getPointer());
264+
bool inserted = ConstraintRestrictions.insert(
265+
std::make_pair(key, restriction)).second;
266+
if (!inserted)
267+
return;
268+
269+
if (isRecordingChanges()) {
270+
recordChange(SolverTrail::Change::addedConversionRestriction(
271+
srcType, dstType));
272+
}
273+
}
274+
275+
void ConstraintSystem::removeConversionRestriction(
276+
Type srcType, Type dstType) {
277+
auto key = std::make_pair(srcType.getPointer(), dstType.getPointer());
278+
bool erased = ConstraintRestrictions.erase(key);
279+
ASSERT(erased);
280+
}
281+
260282
/// Retrieve a dynamic result signature for the given declaration.
261283
static std::tuple<char, ObjCSelector, CanType>
262284
getDynamicResultSignature(ValueDecl *decl) {

0 commit comments

Comments
 (0)