Skip to content

Commit 1cbd7d3

Browse files
authored
Merge pull request swiftlang#77152 from slavapestov/fix-issue-77008
Sema: Give constraints a more dignified retirement
2 parents a7522b2 + 6648508 commit 1cbd7d3

File tree

10 files changed

+58
-42
lines changed

10 files changed

+58
-42
lines changed

include/swift/Sema/CSTrail.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ CLOSURE_CHANGE(RecordedPreconcurrencyClosure)
6969
CONSTRAINT_CHANGE(DisabledConstraint)
7070
CONSTRAINT_CHANGE(FavoredConstraint)
7171
CONSTRAINT_CHANGE(GeneratedConstraint)
72-
CONSTRAINT_CHANGE(RetiredConstraint)
7372

7473
GRAPH_NODE_CHANGE(AddedConstraint)
7574
GRAPH_NODE_CHANGE(RemovedConstraint)
@@ -97,8 +96,9 @@ CHANGE(RecordedCaseLabelItemInfo)
9796
CHANGE(RecordedPotentialThrowSite)
9897
CHANGE(RecordedIsolatedParam)
9998
CHANGE(RecordedKeyPath)
99+
CHANGE(RetiredConstraint)
100100

101-
LAST_CHANGE(RecordedKeyPath)
101+
LAST_CHANGE(RetiredConstraint)
102102

103103
#undef LOCATOR_CHANGE
104104
#undef EXPR_CHANGE

include/swift/Sema/CSTrail.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include "swift/AST/AnyFunctionRef.h"
2121
#include "swift/AST/Type.h"
2222
#include "swift/AST/Types.h"
23+
#include "swift/Sema/Constraint.h"
24+
#include "llvm/ADT/ilist.h"
2325
#include <vector>
2426

2527
namespace llvm {
@@ -103,7 +105,6 @@ class SolverTrail {
103105
Type DstType;
104106
} Restriction;
105107

106-
107108
struct {
108109
GenericTypeParamType *GP;
109110
Type ReqTy;
@@ -119,6 +120,14 @@ class SolverTrail {
119120
Type OldType;
120121
} KeyPath;
121122

123+
struct {
124+
/// It's former position in the inactive constraints list.
125+
llvm::ilist<Constraint>::iterator Where;
126+
127+
/// The constraint.
128+
Constraint *Constraint;
129+
} Retiree;
130+
122131
ConstraintFix *TheFix;
123132
ConstraintLocator *TheLocator;
124133
PackExpansionType *TheExpansion;
@@ -213,6 +222,10 @@ class SolverTrail {
213222
/// Create a change that recorded a key path expression.
214223
static Change RecordedKeyPath(KeyPathExpr *expr);
215224

225+
/// Create a change that removed a constraint from the inactive constraint list.
226+
static Change RetiredConstraint(llvm::ilist<Constraint>::iterator where,
227+
Constraint *constraint);
228+
216229
/// Undo this change, reverting the constraint graph to the state it
217230
/// had prior to this change.
218231
///

include/swift/Sema/ConstraintSystem.h

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2538,13 +2538,6 @@ class ConstraintSystem {
25382538
#define CS_STATISTIC(Name, Description) unsigned Name = 0;
25392539
#include "ConstraintSolverStats.def"
25402540

2541-
/// Mark given constraint as retired along current solver path.
2542-
///
2543-
/// \param constraint The constraint to retire temporarily.
2544-
void retireConstraint(Constraint *constraint) {
2545-
Trail.recordChange(SolverTrail::Change::RetiredConstraint(constraint));
2546-
}
2547-
25482541
/// Add new "generated" constraint along the current solver path.
25492542
///
25502543
/// \param constraint The newly generated constraint.
@@ -3924,7 +3917,10 @@ class ConstraintSystem {
39243917
/// Remove an inactive constraint from the current constraint graph.
39253918
void removeInactiveConstraint(Constraint *constraint) {
39263919
CG.removeConstraint(constraint);
3927-
InactiveConstraints.erase(constraint);
3920+
3921+
auto where = InactiveConstraints.erase(constraint);
3922+
if (solverState)
3923+
recordChange(SolverTrail::Change::RetiredConstraint(where, constraint));
39283924

39293925
if (isDebugMode() && getPhase() == ConstraintSystemPhase::Solving) {
39303926
auto &log = llvm::errs();
@@ -3934,9 +3930,6 @@ class ConstraintSystem {
39343930
solverState->getCurrentIndent() + 4);
39353931
log << ")\n";
39363932
}
3937-
3938-
if (solverState)
3939-
solverState->retireConstraint(constraint);
39403933
}
39413934

39423935
/// Transfer given constraint from to active list

lib/Sema/CSStep.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,13 +425,17 @@ StepResult ComponentStep::take(bool prevFailed) {
425425
case StepKind::Binding:
426426
return suspend(
427427
std::make_unique<TypeVariableStep>(*bestBindings, Solutions));
428-
case StepKind::Disjunction:
428+
case StepKind::Disjunction: {
429+
CS.retireConstraint(disjunction);
429430
return suspend(
430431
std::make_unique<DisjunctionStep>(CS, disjunction, Solutions));
431-
case StepKind::Conjunction:
432+
}
433+
case StepKind::Conjunction: {
434+
CS.retireConstraint(conjunction);
432435
return suspend(
433436
std::make_unique<ConjunctionStep>(CS, conjunction, Solutions));
434437
}
438+
}
435439
llvm_unreachable("Unhandled case in switch!");
436440
}
437441

lib/Sema/CSStep.h

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -202,18 +202,6 @@ class SolverStep {
202202
return StepResult::unsolved(followup);
203203
}
204204

205-
/// Erase constraint from the constraint system (include constraint graph)
206-
/// and return the constraint which follows it.
207-
ConstraintList::iterator erase(Constraint *constraint) {
208-
CS.CG.removeConstraint(constraint);
209-
return CS.InactiveConstraints.erase(constraint);
210-
}
211-
212-
void restore(ConstraintList::iterator &iterator, Constraint *constraint) {
213-
CS.InactiveConstraints.insert(iterator, constraint);
214-
CS.CG.addConstraint(constraint);
215-
}
216-
217205
void recordDisjunctionChoice(ConstraintLocator *disjunctionLocator,
218206
unsigned index) const {
219207
CS.recordDisjunctionChoice(disjunctionLocator, index);
@@ -684,16 +672,14 @@ class TypeVariableStep final : public BindingStep<TypeVarBindingProducer> {
684672
class DisjunctionStep final : public BindingStep<DisjunctionChoiceProducer> {
685673
Constraint *Disjunction;
686674
SmallVector<Constraint *, 4> DisabledChoices;
687-
ConstraintList::iterator AfterDisjunction;
688675

689676
std::optional<Score> BestNonGenericScore;
690677
std::optional<std::pair<Constraint *, Score>> LastSolvedChoice;
691678

692679
public:
693680
DisjunctionStep(ConstraintSystem &cs, Constraint *disjunction,
694681
SmallVectorImpl<Solution> &solutions)
695-
: BindingStep(cs, {cs, disjunction}, solutions), Disjunction(disjunction),
696-
AfterDisjunction(erase(disjunction)) {
682+
: BindingStep(cs, {cs, disjunction}, solutions), Disjunction(disjunction) {
697683
assert(Disjunction->getKind() == ConstraintKind::Disjunction);
698684
pruneOverloadSet(Disjunction);
699685
++cs.solverState->NumDisjunctions;
@@ -702,8 +688,6 @@ class DisjunctionStep final : public BindingStep<DisjunctionChoiceProducer> {
702688
~DisjunctionStep() override {
703689
// Rewind back any changes left after attempting last choice.
704690
ActiveChoice.reset();
705-
// Return disjunction constraint back to the system.
706-
restore(AfterDisjunction, Disjunction);
707691
// Re-enable previously disabled overload choices.
708692
for (auto *choice : DisabledChoices)
709693
choice->setEnabled();
@@ -919,10 +903,6 @@ class ConjunctionStep : public BindingStep<ConjunctionElementProducer> {
919903

920904
/// Conjunction constraint associated with this step.
921905
Constraint *Conjunction;
922-
/// Position of the conjunction in the inactive constraints
923-
/// list which is required to re-instate it to the system
924-
/// after this step is done.
925-
ConstraintList::iterator AfterConjunction;
926906

927907
/// Indicates that one of the elements failed inference.
928908
bool HadFailure = false;
@@ -950,7 +930,7 @@ class ConjunctionStep : public BindingStep<ConjunctionElementProducer> {
950930
conjunction->isIsolated() ? IsolatedSolutions : solutions),
951931
BestScore(getBestScore()),
952932
OuterScopeCount(cs.CountScopes, 0), Conjunction(conjunction),
953-
AfterConjunction(erase(conjunction)), OuterSolutions(solutions) {
933+
OuterSolutions(solutions) {
954934
assert(conjunction->getKind() == ConstraintKind::Conjunction);
955935

956936
// Make a snapshot of the constraint system state before conjunction.
@@ -969,9 +949,6 @@ class ConjunctionStep : public BindingStep<ConjunctionElementProducer> {
969949
// Return all of the type variables and constraints back.
970950
Snapshot.reset();
971951

972-
// Restore conjunction constraint.
973-
restore(AfterConjunction, Conjunction);
974-
975952
// Restore best score only if conjunction fails because
976953
// successful outcome should keep a score set by `restoreOuterState`.
977954
if (HadFailure)

lib/Sema/CSTrail.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,16 @@ SolverTrail::Change::RecordedKeyPath(KeyPathExpr *expr) {
296296
return result;
297297
}
298298

299+
SolverTrail::Change
300+
SolverTrail::Change::RetiredConstraint(ConstraintList::iterator where,
301+
Constraint *constraint) {
302+
Change result;
303+
result.Kind = ChangeKind::RetiredConstraint;
304+
result.Retiree.Where = where;
305+
result.Retiree.Constraint = constraint;
306+
return result;
307+
}
308+
299309
SyntacticElementTargetKey
300310
SolverTrail::Change::getSyntacticElementTargetKey() const {
301311
ASSERT(Kind == ChangeKind::RecordedTarget);
@@ -481,7 +491,8 @@ void SolverTrail::Change::undo(ConstraintSystem &cs) const {
481491
}
482492

483493
case ChangeKind::RetiredConstraint:
484-
cs.InactiveConstraints.push_back(TheConstraint.Constraint);
494+
cs.InactiveConstraints.insert(Retiree.Where,
495+
Retiree.Constraint);
485496
break;
486497
}
487498
}
@@ -674,6 +685,13 @@ void SolverTrail::Change::dump(llvm::raw_ostream &out,
674685
simple_display(out, KeyPath.Expr);
675686
out << ")\n";
676687
break;
688+
689+
case ChangeKind::RetiredConstraint:
690+
out << "(RetiredConstraint ";
691+
TheConstraint.Constraint->print(out, &cs.getASTContext().SourceMgr,
692+
indent + 2);
693+
out << ")\n";
694+
break;
677695
}
678696
}
679697

test/Constraints/issue-77008.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// RUN: not %target-swift-frontend -typecheck %s
2+
3+
// Just don't crash.
4+
5+
Binding<Bool>Binding<Bool>

validation-test/Sema/type_checker_perf/fast/borderline_flat_map_operator_mix.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// RUN: %target-typecheck-verify-swift -solver-expression-time-threshold=10
22

3+
// REQUIRES: no_asan
4+
35
struct S {
46
var t: Double
57

validation-test/Sema/type_checker_perf/slow/coerce_literal_linear_combo.swift.gyb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// RUN: %scale-test --invert-result --begin 2 --end 5 --step 1 --select NumLeafScopes %s
22

3+
// REQUIRES: no_asan
4+
35
func g<T: Equatable>(_: T, _: T) {}
46

57
let base: UInt64 = 0

validation-test/Sema/type_checker_perf/slow/simd_scalar_multiple.swift.gyb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// RUN: %scale-test --invert-result --begin 1 --end 5 --step 1 --select NumLeafScopes %s
22

3+
// REQUIRES: no_asan
4+
35
func f(c: Float, a: SIMD2<Float>) -> SIMD2<Float> {
46
return (c * a)
57
%for i in range(1, N):

0 commit comments

Comments
 (0)