Skip to content

Commit 411c590

Browse files
committed
Sema: Record key path component types in the trail
1 parent 7ea9750 commit 411c590

File tree

4 files changed

+68
-29
lines changed

4 files changed

+68
-29
lines changed

include/swift/Sema/CSTrail.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ class SolverTrail {
8080
RecordedDefaultedConstraint,
8181
/// Recorded an assignment of a type to an AST node.
8282
RecordedNodeType,
83+
/// Recorded an assignment of a type to a keypath component.
84+
RecordedKeyPathComponentType,
8385
};
8486

8587
/// A change made to the constraint system.
@@ -149,6 +151,11 @@ class SolverTrail {
149151
Type OldType;
150152
} Node;
151153

154+
struct {
155+
const KeyPathExpr *Expr;
156+
Type OldType;
157+
} KeyPath;
158+
152159
ConstraintLocator *Locator;
153160
PackExpansionType *ExpansionTy;
154161
PackElementExpr *ElementExpr;
@@ -231,6 +238,11 @@ class SolverTrail {
231238
/// Create a change that recorded an assignment of a type to an AST node.
232239
static Change recordedNodeType(ASTNode node, Type oldType);
233240

241+
/// Create a change that recorded an assignment of a type to an AST node.
242+
static Change recordedKeyPathComponentType(const KeyPathExpr *expr,
243+
unsigned component,
244+
Type oldType);
245+
234246
/// Undo this change, reverting the constraint graph to the state it
235247
/// had prior to this change.
236248
///

include/swift/Sema/ConstraintSystem.h

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2265,11 +2265,6 @@ class ConstraintSystem {
22652265
Type>
22662266
KeyPathComponentTypes;
22672267

2268-
/// Same as \c addedNodeTypes for \c KeyPathComponentTypes.
2269-
llvm::SmallVector<
2270-
std::tuple<const KeyPathExpr *, /*component index=*/unsigned, Type>>
2271-
addedKeyPathComponentTypes;
2272-
22732268
/// Maps a key path root, value, and decl context to the key path expression.
22742269
llvm::MapVector<const KeyPathExpr *,
22752270
std::tuple</*root=*/TypeVariableType *,
@@ -2890,8 +2885,6 @@ class ConstraintSystem {
28902885
/// FIXME: Remove this.
28912886
unsigned numFixes;
28922887

2893-
unsigned numAddedKeyPathComponentTypes;
2894-
28952888
unsigned numDisabledConstraints;
28962889

28972890
unsigned numFavoredConstraints;
@@ -3234,25 +3227,44 @@ class ConstraintSystem {
32343227
}
32353228
}
32363229

3230+
/// Check to see if we have a type for a node.
3231+
bool hasType(ASTNode node) const {
3232+
assert(!node.isNull() && "Expected non-null node");
3233+
return NodeTypes.count(node) > 0;
3234+
}
3235+
32373236
/// Set the type in our type map for a given expression. The side
32383237
/// map is used throughout the expression type checker in order to
32393238
/// avoid mutating expressions until we know we have successfully
32403239
/// type-checked them.
32413240
void setType(const KeyPathExpr *KP, unsigned I, Type T) {
3242-
assert(KP && "Expected non-null key path parameter!");
3243-
assert(T && "Expected non-null type!");
3241+
ASSERT(KP && "Expected non-null key path parameter!");
3242+
ASSERT(T && "Expected non-null type!");
32443243

32453244
Type &entry = KeyPathComponentTypes[{KP, I}];
32463245
Type oldType = entry;
32473246
entry = T;
32483247

3249-
addedKeyPathComponentTypes.push_back(std::make_tuple(KP, I, oldType));
3248+
if (oldType.getPointer() != T.getPointer()) {
3249+
if (isRecordingChanges()) {
3250+
recordChange(
3251+
SolverTrail::Change::recordedKeyPathComponentType(
3252+
KP, I, oldType));
3253+
}
3254+
}
32503255
}
32513256

3252-
/// Check to see if we have a type for a node.
3253-
bool hasType(ASTNode node) const {
3254-
assert(!node.isNull() && "Expected non-null node");
3255-
return NodeTypes.count(node) > 0;
3257+
void restoreType(const KeyPathExpr *KP, unsigned I, Type T) {
3258+
ASSERT(KP && "Expected non-null key path parameter!");
3259+
3260+
if (T) {
3261+
auto found = KeyPathComponentTypes.find({KP, I});
3262+
ASSERT(found != KeyPathComponentTypes.end());
3263+
found->second = T;
3264+
} else {
3265+
bool erased = KeyPathComponentTypes.erase({KP, I});
3266+
ASSERT(erased);
3267+
}
32563268
}
32573269

32583270
bool hasType(const KeyPathExpr *KP, unsigned I) const {

lib/Sema/CSSolver.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,6 @@ ConstraintSystem::SolverScope::SolverScope(ConstraintSystem &cs)
663663

664664
numTypeVariables = cs.TypeVariables.size();
665665
numFixes = cs.Fixes.size();
666-
numAddedKeyPathComponentTypes = cs.addedKeyPathComponentTypes.size();
667666
numKeyPaths = cs.KeyPaths.size();
668667
numDisabledConstraints = cs.solverState->getNumDisabledConstraints();
669668
numFavoredConstraints = cs.solverState->getNumFavoredConstraints();
@@ -717,19 +716,6 @@ ConstraintSystem::SolverScope::~SolverScope() {
717716
// constraints introduced by the current scope.
718717
cs.solverState->rollback(this);
719718

720-
// Remove any node types we registered.
721-
for (unsigned i : reverse(range(numAddedKeyPathComponentTypes,
722-
cs.addedKeyPathComponentTypes.size()))) {
723-
auto KeyPath = std::get<0>(cs.addedKeyPathComponentTypes[i]);
724-
auto KeyPathIndex = std::get<1>(cs.addedKeyPathComponentTypes[i]);
725-
if (Type oldType = std::get<2>(cs.addedKeyPathComponentTypes[i])) {
726-
cs.KeyPathComponentTypes[{KeyPath, KeyPathIndex}] = oldType;
727-
} else {
728-
cs.KeyPathComponentTypes.erase({KeyPath, KeyPathIndex});
729-
}
730-
}
731-
truncate(cs.addedKeyPathComponentTypes, numAddedKeyPathComponentTypes);
732-
733719
/// Remove any key path expressions.
734720
truncate(cs.KeyPaths, numKeyPaths);
735721

lib/Sema/CSTrail.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,18 @@ SolverTrail::Change::recordedNodeType(ASTNode node, Type oldType) {
234234
return result;
235235
}
236236

237+
SolverTrail::Change
238+
SolverTrail::Change::recordedKeyPathComponentType(const KeyPathExpr *expr,
239+
unsigned component,
240+
Type oldType) {
241+
Change result;
242+
result.Kind = ChangeKind::RecordedKeyPathComponentType;
243+
result.Options = component;
244+
result.KeyPath.Expr = expr;
245+
result.KeyPath.OldType = oldType;
246+
return result;
247+
}
248+
237249
void SolverTrail::Change::undo(ConstraintSystem &cs) const {
238250
auto &cg = cs.getConstraintGraph();
239251

@@ -326,6 +338,10 @@ void SolverTrail::Change::undo(ConstraintSystem &cs) const {
326338
case ChangeKind::RecordedNodeType:
327339
cs.restoreType(Node.Node, Node.OldType);
328340
break;
341+
342+
case ChangeKind::RecordedKeyPathComponentType:
343+
cs.restoreType(KeyPath.Expr, Options, KeyPath.OldType);
344+
break;
329345
}
330346
}
331347

@@ -482,7 +498,9 @@ void SolverTrail::Change::dump(llvm::raw_ostream &out,
482498

483499
case ChangeKind::RecordedPackEnvironment:
484500
// FIXME: Print short form of PackExpansionExpr
485-
out << "(recorded pack environment)\n";
501+
out << "(recorded pack environment";
502+
simple_display(out, ElementExpr);
503+
out << "\n";
486504
break;
487505

488506
case ChangeKind::RecordedDefaultedConstraint:
@@ -501,6 +519,17 @@ void SolverTrail::Change::dump(llvm::raw_ostream &out,
501519
out << "null";
502520
out << ")\n";
503521
break;
522+
523+
case ChangeKind::RecordedKeyPathComponentType:
524+
out << "(recorded key path ";
525+
simple_display(out, KeyPath.Expr);
526+
out << " with component type ";
527+
if (Node.OldType)
528+
Node.OldType->print(out, PO);
529+
else
530+
out << "null";
531+
out << " for component " << Options << ")\n";
532+
break;
504533
}
505534
}
506535

0 commit comments

Comments
 (0)