Skip to content

Commit 127ff11

Browse files
authored
Merge pull request #60828 from amritpan/print-simplification
[ConstraintSystem] Print constraint simplification in type inference debug output
2 parents b5f209d + 1151960 commit 127ff11

File tree

6 files changed

+87
-18
lines changed

6 files changed

+87
-18
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4421,7 +4421,7 @@ class ConstraintSystem {
44214421

44224422
if (isDebugMode()) {
44234423
auto &log = llvm::errs();
4424-
log.indent(solverState ? solverState->getCurrentIndent() : 0)
4424+
log.indent(solverState ? solverState->getCurrentIndent() + 4 : 0)
44254425
<< "(failed constraint ";
44264426
constraint->print(log, &getASTContext().SourceMgr);
44274427
log << ")\n";
@@ -4444,6 +4444,14 @@ class ConstraintSystem {
44444444
// Add this constraint to the constraint graph.
44454445
CG.addConstraint(constraint);
44464446

4447+
if (isDebugMode() && getPhase() == ConstraintSystemPhase::Solving) {
4448+
auto &log = llvm::errs();
4449+
log.indent(solverState->getCurrentIndent() + 4) << "(added constraint: ";
4450+
constraint->print(log, &getASTContext().SourceMgr,
4451+
solverState->getCurrentIndent() + 4);
4452+
log << ")\n";
4453+
}
4454+
44474455
// Record this as a newly-generated constraint.
44484456
if (solverState)
44494457
solverState->addGeneratedConstraint(constraint);
@@ -4454,6 +4462,15 @@ class ConstraintSystem {
44544462
CG.removeConstraint(constraint);
44554463
InactiveConstraints.erase(constraint);
44564464

4465+
if (isDebugMode() && getPhase() == ConstraintSystemPhase::Solving) {
4466+
auto &log = llvm::errs();
4467+
log.indent(solverState->getCurrentIndent() + 4)
4468+
<< "(removed constraint: ";
4469+
constraint->print(log, &getASTContext().SourceMgr,
4470+
solverState->getCurrentIndent() + 4);
4471+
log << ")\n";
4472+
}
4473+
44574474
if (solverState)
44584475
solverState->retireConstraint(constraint);
44594476
}

lib/Sema/CSSolver.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,24 +345,62 @@ bool ConstraintSystem::simplify() {
345345
auto *constraint = &ActiveConstraints.front();
346346
deactivateConstraint(constraint);
347347

348+
if (isDebugMode()) {
349+
auto &log = llvm::errs();
350+
log.indent(solverState->getCurrentIndent());
351+
log << "(considering -> ";
352+
constraint->print(log, &getASTContext().SourceMgr);
353+
log << "\n";
354+
355+
// {Dis, Con}junction are returned unsolved in \c simplifyConstraint() and
356+
// handled separately by solver steps.
357+
if (constraint->getKind() != ConstraintKind::Disjunction &&
358+
constraint->getKind() != ConstraintKind::Conjunction) {
359+
log.indent(solverState->getCurrentIndent() + 2)
360+
<< "(simplification result:\n";
361+
}
362+
}
363+
348364
// Simplify this constraint.
349365
switch (simplifyConstraint(*constraint)) {
350366
case SolutionKind::Error:
351367
retireFailedConstraint(constraint);
368+
if (isDebugMode()) {
369+
auto &log = llvm::errs();
370+
log.indent(solverState->getCurrentIndent() + 2) << ")\n";
371+
log.indent(solverState->getCurrentIndent() + 2) << "(outcome: error)\n";
372+
}
352373
break;
353374

354375
case SolutionKind::Solved:
355376
if (solverState)
356377
++solverState->NumSimplifiedConstraints;
357378
retireConstraint(constraint);
379+
if (isDebugMode()) {
380+
auto &log = llvm::errs();
381+
log.indent(solverState->getCurrentIndent() + 2) << ")\n";
382+
log.indent(solverState->getCurrentIndent() + 2)
383+
<< "(outcome: simplified)\n";
384+
}
358385
break;
359386

360387
case SolutionKind::Unsolved:
361388
if (solverState)
362389
++solverState->NumUnsimplifiedConstraints;
390+
if (isDebugMode()) {
391+
auto &log = llvm::errs();
392+
log.indent(solverState->getCurrentIndent() + 2) << ")\n";
393+
log.indent(solverState->getCurrentIndent() + 2)
394+
<< "(outcome: unsolved)\n";
395+
}
363396
break;
364397
}
365398

399+
if (isDebugMode()) {
400+
auto &log = llvm::errs();
401+
log.indent(solverState->getCurrentIndent()) << ")\n";
402+
}
403+
366404
// Check whether a constraint failed. If so, we're done.
367405
if (failedConstraint) {
368406
return true;

test/Concurrency/async_overload_filtering.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ var a: String? = nil
1818

1919
// CHECK: attempting disjunction choice $T0 bound to decl async_overload_filtering.(file).filter_async(fn2:)
2020
// CHECK-NEXT: overload set choice binding $T0 := {{.*}}
21-
// CHECK-NEXT: increasing 'sync-in-asynchronous' score by 1
22-
// CHECK-NEXT: solution is worse than the best solution
21+
// CHECK-NEXT: (considering -> ({{.*}}) -> {{.*}} applicable fn {{.*}}
22+
// CHECK: increasing 'sync-in-asynchronous' score by 1
23+
// CHECK: solution is worse than the best solution
2324
filter_async {
2425
Obj()
2526
}.op("" + (a ?? "a"))

test/Constraints/common_type.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@ func f(_: Double) -> Y { return Y() }
2828

2929
func testCallCommonType() {
3030
// CHECK: overload set choice binding $T{{[0-9]+}} := (Int) -> X
31-
// CHECK-NEXT: (common result type for $T{{[0-9]+}} is Int)
31+
// CHECK: (considering -> $T{{[0-9]+}}[.g: value] == [[G:\$T[0-9]+]]
32+
// CHECK: (common result type for [[G]] is Int)
3233
// CHECK: (overload set choice binding $T{{[0-9]+}} := (Double) -> Y)
33-
// CHECK-NEXT: (common result type for $T{{[0-9]+}} is Double)
34+
// CHECK: (considering -> $T{{[0-9]+}}[.g: value] == [[F:\$T[0-9]+]]
35+
// CHECK: (common result type for [[F]] is Double)
3436
_ = f(0).g(0)
3537
}
3638

test/Constraints/one_way_solve.swift

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ func takeDoubleAndBool(_: Double, _: Bool) { }
77

88
func testTernaryOneWay(b: Bool, b2: Bool) {
99
// CHECK: ---Connected components---
10-
// CHECK-NEXT: 3: $T10 depends on 1
11-
// CHECK-NEXT: 1: $T5 $T8 $T9 depends on 0, 2
12-
// CHECK-NEXT: 2: $T7
13-
// CHECK-NEXT: 0: $T4
14-
// CHECK-NEXT: 4: $T11 $T13 $T14
10+
// CHECK-NEXT: 3: $T{{[0-9]+}} depends on 1
11+
// CHECK-NEXT: 1: $T{{[0-9]+}} $T{{[0-9]+}} $T{{[0-9]+}} depends on 0, 2
12+
// CHECK-NEXT: 2: $T{{[0-9]+}}
13+
// CHECK-NEXT: 0: $T{{[0-9]+}}
14+
// CHECK-NEXT: 4: $T{{[0-9]+}} $T{{[0-9]+}} $T{{[0-9]+}}
1515
takeDoubleAndBool(
1616
Builtin.one_way(
1717
b ? Builtin.one_way(3.14159) : Builtin.one_way(2.71828)),
@@ -23,22 +23,25 @@ func int8Or16(_ x: Int16) -> Int16 { return x }
2323

2424
func testTernaryOneWayOverload(b: Bool) {
2525
// CHECK: ---Connected components---
26-
// CHECK: 1: $T5 $T10 $T11 depends on 0, 2
27-
// CHECK: 2: $T7 $T8 $T9
28-
// CHECK: 0: $T2 $T3 $T4
26+
// CHECK: 1: [[A:\$T[0-9]+]] [[B:\$T[0-9]+]] [[C:\$T[0-9]+]] depends on 0, 2
27+
// CHECK: 2: $T{{[0-9]+}} $T{{[0-9]+}} $T{{[0-9]+}}
28+
// CHECK: 0: $T{{[0-9]+}} $T{{[0-9]+}} $T{{[0-9]+}}
2929

3030
// CHECK: solving component #1
31-
// CHECK: (attempting type variable $T11 := Int8
31+
// CHECK: (attempting type variable [[C]] := Int8
3232

3333
// CHECK: solving component #1
34-
// CHECK: (attempting type variable $T11 := Int8
34+
// CHECK: (attempting type variable [[C]] := Int8
3535

3636
// CHECK: solving component #1
37-
// CHECK: (attempting type variable $T11 := Int8
37+
// CHECK: (attempting type variable [[C]] := Int8
3838

3939
// CHECK: solving component #1
40-
// CHECK: (attempting type variable $T11 := Int8
41-
// CHECK: (found solution: [component: non-default literal(s), value: 2] [component: use of overloaded unapplied function(s), value: 2])
40+
// CHECK: (attempting type variable [[C]] := Int8
41+
// CHECK: (considering -> $T{{[0-9]+}} conv [[C]]
42+
// CHECK: (considering -> $T{{[0-9]+}} conv [[C]]
43+
// CHECK: (considering -> [[C]] conv Int8
44+
// CHECK: (found solution: [component: non-default literal(s), value: 2] [component: use of overloaded unapplied function(s), value: 2])
4245

4346
// CHECK: (composed solution: [component: non-default literal(s), value: 2] [component: use of overloaded unapplied function(s), value: 2])
4447
// CHECK-NOT: (composed solution: [component: non-default literal(s), value: 2] [component: use of overloaded unapplied function(s), value: 2])

test/Constraints/overload_filtering.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ func testSubscript(x: X, i: Int) {
3535
func testUnresolvedMember(i: Int) -> X {
3636
// CHECK: disabled disjunction term {{.*}} bound to decl overload_filtering.(file).X.init(_:)
3737
// CHECK-NEXT: disabled disjunction term {{.*}} bound to decl overload_filtering.(file).X.init(_:_:_:)
38+
// CHECK-NEXT: (removed constraint: disjunction
39+
// CHECK-NEXT: > [[A:\$T[0-9]+]] bound to decl overload_filtering
40+
// CHECK-NEXT: > [disabled] [[A]] bound to decl overload_filtering
41+
// CHECK-NEXT: > [disabled] [[A]] bound to decl overload_filtering
3842
// CHECK-NEXT: introducing single enabled disjunction term {{.*}} bound to decl overload_filtering.(file).X.init(_:_:)
3943
return .init(i, i)
4044
}
@@ -56,6 +60,10 @@ func test_member_filtering() {
5660
func test(s: S) {
5761
// CHECK: disabled disjunction term {{.*}} bound to decl overload_filtering.(file).test_member_filtering().S.bar(v:)
5862
// CHECK-NEXT: disabled disjunction term {{.*}} bound to decl overload_filtering.(file).test_member_filtering().S.bar(a:b:)
63+
// CHECK-NEXT: (removed constraint: disjunction
64+
// CHECK-NEXT: > [[B:\$T[0-9]+]] bound to decl overload_filtering
65+
// CHECK-NEXT: > [disabled] [[B]] bound to decl overload_filtering
66+
// CHECK-NEXT: > [disabled] [[B]] bound to decl overload_filtering
5967
// CHECK-NEXT: introducing single enabled disjunction term {{.*}} bound to decl overload_filtering.(file).test_member_filtering().S.bar
6068
s.foo(42).bar(42)
6169
}

0 commit comments

Comments
 (0)