Skip to content

Commit 7f08d40

Browse files
authored
Merge pull request #60443 from amritpan/improve-solver-step-printing
[ConstraintSystem] Improve solver step printing in the type inference algorithm debug output
2 parents cfe90e9 + e7600fe commit 7f08d40

File tree

7 files changed

+109
-45
lines changed

7 files changed

+109
-45
lines changed

Diff for: include/swift/Sema/ConstraintSystem.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ class TypeVariableType::Implementation {
626626

627627
/// Print the type variable to the given output stream.
628628
void print(llvm::raw_ostream &OS);
629-
629+
630630
private:
631631
StringRef getTypeVariableOptions(TypeVariableOptions TVO) const {
632632
#define ENTRY(Kind, String) case TypeVariableOptions::Kind: return String

Diff for: lib/Sema/CSBindings.cpp

+77-35
Original file line numberDiff line numberDiff line change
@@ -1657,9 +1657,11 @@ void BindingSet::dump(llvm::raw_ostream &out, unsigned indent) const {
16571657

16581658
out.indent(indent);
16591659
out << "(";
1660-
if (auto typeVar = getTypeVariable())
1661-
out << "$T" << typeVar->getImpl().getID() << " ";
1662-
1660+
if (auto typeVar = getTypeVariable()) {
1661+
typeVar->print(out, PO);
1662+
out << " ";
1663+
}
1664+
16631665
std::vector<std::string> attributes;
16641666
if (isDirectHole())
16651667
attributes.push_back("hole");
@@ -1722,56 +1724,96 @@ void BindingSet::dump(llvm::raw_ostream &out, unsigned indent) const {
17221724

17231725
auto numDefaultable = getNumViableDefaultableBindings();
17241726
if (numDefaultable > 0)
1725-
out << "#defaultable_bindings: " << numDefaultable << " ";
1727+
out << "[#defaultable_bindings: " << numDefaultable << "] ";
17261728

1727-
auto printBinding = [&](const PotentialBinding &binding) {
1728-
auto type = binding.BindingType;
1729-
switch (binding.Kind) {
1730-
case AllowedBindingKind::Exact:
1731-
break;
1729+
struct PrintableBinding {
1730+
private:
1731+
enum class BindingKind { Exact, Subtypes, Supertypes, Literal };
1732+
BindingKind Kind;
1733+
Type BindingType;
1734+
PrintableBinding(BindingKind kind, Type bindingType)
1735+
: Kind(kind), BindingType(bindingType) {}
17321736

1733-
case AllowedBindingKind::Subtypes:
1734-
out << "(subtypes of) ";
1735-
break;
1737+
public:
1738+
static PrintableBinding supertypesOf(Type binding) {
1739+
return PrintableBinding{BindingKind::Supertypes, binding};
1740+
}
1741+
1742+
static PrintableBinding subtypesOf(Type binding) {
1743+
return PrintableBinding{BindingKind::Subtypes, binding};
1744+
}
1745+
1746+
static PrintableBinding exact(Type binding) {
1747+
return PrintableBinding{BindingKind::Exact, binding};
1748+
}
1749+
1750+
static PrintableBinding literalDefaultType(Type binding) {
1751+
return PrintableBinding{BindingKind::Literal, binding};
1752+
}
17361753

1737-
case AllowedBindingKind::Supertypes:
1738-
out << "(supertypes of) ";
1739-
break;
1754+
void print(llvm::raw_ostream &out, const PrintOptions &PO,
1755+
unsigned indent = 0) const {
1756+
switch (Kind) {
1757+
case BindingKind::Exact:
1758+
break;
1759+
case BindingKind::Subtypes:
1760+
out << "(subtypes of) ";
1761+
break;
1762+
case BindingKind::Supertypes:
1763+
out << "(supertypes of) ";
1764+
break;
1765+
case BindingKind::Literal:
1766+
out << "(default type of literal) ";
1767+
break;
1768+
}
1769+
BindingType.print(out);
17401770
}
1741-
if (auto *literal = binding.getDefaultedLiteralProtocol())
1742-
out << "(default from " << literal->getName() << ") ";
1743-
out << type.getString(PO);
17441771
};
17451772

17461773
out << "[with possible bindings: ";
1747-
interleave(Bindings, printBinding, [&]() { out << "; "; });
1748-
if (!Literals.empty()) {
1749-
std::vector<std::string> defaultLiterals;
1750-
for (const auto &literal : Literals) {
1751-
if (literal.second.viableAsBinding()) {
1752-
auto defaultWithType = "(default type of literal) " +
1753-
literal.second.getDefaultType().getString(PO);
1754-
defaultLiterals.push_back(defaultWithType);
1755-
}
1774+
SmallVector<PrintableBinding, 2> potentialBindings;
1775+
for (const auto &binding : Bindings) {
1776+
switch (binding.Kind) {
1777+
case AllowedBindingKind::Exact:
1778+
potentialBindings.push_back(PrintableBinding::exact(binding.BindingType));
1779+
break;
1780+
case AllowedBindingKind::Supertypes:
1781+
potentialBindings.push_back(
1782+
PrintableBinding::supertypesOf(binding.BindingType));
1783+
break;
1784+
case AllowedBindingKind::Subtypes:
1785+
potentialBindings.push_back(
1786+
PrintableBinding::subtypesOf(binding.BindingType));
1787+
break;
17561788
}
1757-
interleave(defaultLiterals, out, ", ");
17581789
}
1759-
if (Bindings.empty() && Literals.empty()) {
1790+
for (const auto &literal : Literals) {
1791+
if (literal.second.viableAsBinding()) {
1792+
potentialBindings.push_back(PrintableBinding::literalDefaultType(
1793+
literal.second.getDefaultType()));
1794+
}
1795+
}
1796+
if (potentialBindings.empty()) {
17601797
out << "<empty>";
1798+
} else {
1799+
interleave(
1800+
potentialBindings,
1801+
[&](const PrintableBinding &binding) { binding.print(out, PO); },
1802+
[&] { out << ", "; });
17611803
}
17621804
out << "]";
17631805

17641806
if (!Defaults.empty()) {
1765-
out << "[defaults: ";
1807+
out << " [defaults: ";
17661808
for (const auto &entry : Defaults) {
17671809
auto *constraint = entry.second;
1768-
PotentialBinding binding{constraint->getSecondType(),
1769-
AllowedBindingKind::Exact, constraint};
1770-
printBinding(binding);
1810+
auto defaultBinding =
1811+
PrintableBinding::exact(constraint->getSecondType());
1812+
defaultBinding.print(out, PO);
17711813
}
1772-
out << "] ";
1814+
out << "]";
17731815
}
1774-
out << ")\n";
1816+
out << ")";
17751817
}
17761818

17771819
// Given a possibly-Optional type, return the direct superclass of the

Diff for: lib/Sema/CSGen.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -4207,6 +4207,7 @@ bool ConstraintSystem::generateConstraints(
42074207
print(log, expr);
42084208
log << "\n";
42094209
print(log);
4210+
log << "\n";
42104211
}
42114212

42124213
return false;

Diff for: lib/Sema/CSStep.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ StepResult ComponentStep::take(bool prevFailed) {
352352
auto bestBindings = CS.determineBestBindings([&](const BindingSet &bindings) {
353353
if (CS.isDebugMode() && bindings.hasViableBindings()) {
354354
bindings.dump(bos, CS.solverState->getCurrentIndent() + 2);
355+
bos << "\n";
355356
}
356357
});
357358

@@ -875,6 +876,10 @@ StepResult ConjunctionStep::resume(bool prevFailed) {
875876
// attempted to apply information gained from the
876877
// isolated constraint to the outer context.
877878
if (Snapshot && Snapshot->isScoped()) {
879+
Snapshot.reset();
880+
if (CS.isDebugMode())
881+
getDebugLogger() << ")\n";
882+
878883
return done(/*isSuccess=*/!prevFailed);
879884
}
880885

Diff for: lib/Sema/CSStep.h

-3
Original file line numberDiff line numberDiff line change
@@ -999,9 +999,6 @@ class ConjunctionStep : public BindingStep<ConjunctionElementProducer> {
999999
auto remainingTime = OuterTimeRemaining->second;
10001000
CS.Timer.emplace(anchor, CS, remainingTime);
10011001
}
1002-
1003-
if (CS.isDebugMode())
1004-
getDebugLogger() << ")\n";
10051002
}
10061003

10071004
StepResult resume(bool prevFailed) override;

Diff for: lib/Sema/ConstraintSystem.cpp

+22-4
Original file line numberDiff line numberDiff line change
@@ -3547,10 +3547,28 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
35473547
if (isDebugMode()) {
35483548
PrintOptions PO;
35493549
PO.PrintTypesForDebugging = true;
3550-
llvm::errs().indent(solverState ? solverState->getCurrentIndent() : 2)
3551-
<< "(overload set choice binding "
3552-
<< boundType->getString(PO) << " := "
3553-
<< adjustedRefType->getString(PO) << ")\n";
3550+
3551+
auto &log = llvm::errs();
3552+
log.indent(solverState ? solverState->getCurrentIndent() : 2);
3553+
log << "(overload set choice binding ";
3554+
boundType->print(log, PO);
3555+
log << " := ";
3556+
adjustedRefType->print(log, PO);
3557+
3558+
auto openedAtLoc = getOpenedTypes(locator);
3559+
if (!openedAtLoc.empty()) {
3560+
log << " [";
3561+
llvm::interleave(
3562+
openedAtLoc.begin(), openedAtLoc.end(),
3563+
[&](OpenedType opened) {
3564+
opened.second->getImpl().getGenericParameter()->print(log, PO);
3565+
log << " := ";
3566+
Type(opened.second).print(log, PO);
3567+
},
3568+
[&]() { log << ", "; });
3569+
log << "]";
3570+
}
3571+
log << ")\n";
35543572
}
35553573

35563574
if (auto *decl = choice.getDeclOrNull()) {

Diff for: lib/Sema/TypeCheckConstraints.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -1299,9 +1299,9 @@ void Solution::dump(raw_ostream &out) const {
12991299
if (!overloadChoices.empty()) {
13001300
out << "\nOverload choices:";
13011301
for (auto ovl : overloadChoices) {
1302-
out.indent(2);
13031302
if (ovl.first) {
13041303
out << "\n";
1304+
out.indent(2);
13051305
ovl.first->dump(sm, out);
13061306
}
13071307

@@ -1466,16 +1466,17 @@ void ConstraintSystem::print(raw_ostream &out) const {
14661466
});
14671467
for (auto tv : typeVariables) {
14681468
out.indent(2);
1469-
tv->getImpl().print(out);
14701469
auto rep = getRepresentative(tv);
14711470
if (rep == tv) {
14721471
if (auto fixed = getFixedType(tv)) {
1472+
tv->getImpl().print(out);
14731473
out << " as ";
14741474
Type(fixed).print(out, PO);
14751475
} else {
14761476
const_cast<ConstraintSystem *>(this)->getBindingsFor(tv).dump(out, 1);
14771477
}
14781478
} else {
1479+
tv->getImpl().print(out);
14791480
out << " equivalent to ";
14801481
Type(rep).print(out, PO);
14811482
}

0 commit comments

Comments
 (0)