Skip to content

Commit 9d13361

Browse files
committed
[AST] Introduce a minimal SubstitutionMap dump for use inside expressions.
Within a dump of a DeclRef (or, more likely, a larger entity that includes one), the full multiline details of a substitution map are likely to not be hugely relevant, and just get in the way of understanding the interesting parts of the dump. Thus, this is a variant that is a single line and just includes the substitutions; the conformances (or, at least, the protocols involved) can be inferred from the generic signature combined with those substitutions. The style is controlled via a enum rather than a boolean, to avoid problems with trying to pass an indent like `map->dump(out, indent)`, where the integer indent coerces to a bool, rather than error. Fixes rdar://problem/40074968.
1 parent dad4169 commit 9d13361

File tree

4 files changed

+30
-7
lines changed

4 files changed

+30
-7
lines changed

include/swift/AST/SubstitutionMap.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,12 @@ class SubstitutionMap {
218218
/// Verify that this substitution map is valid.
219219
void verify() const;
220220

221+
/// Whether to dump the full substitution map, or just a minimal useful subset
222+
/// (on a single line).
223+
enum class DumpStyle { Minimal, Full };
221224
/// Dump the contents of this substitution map for debugging purposes.
222-
void dump(llvm::raw_ostream &out, unsigned indent = 0) const;
225+
void dump(llvm::raw_ostream &out, DumpStyle style = DumpStyle::Full,
226+
unsigned indent = 0) const;
223227

224228
LLVM_ATTRIBUTE_DEPRECATED(void dump() const, "only for use in the debugger");
225229

lib/AST/ASTDumper.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "swift/AST/ParameterList.h"
2424
#include "swift/AST/ProtocolConformance.h"
2525
#include "swift/AST/TypeVisitor.h"
26+
#include "swift/Basic/Defer.h"
2627
#include "swift/Basic/QuotedString.h"
2728
#include "swift/Basic/STLExtras.h"
2829
#include "llvm/ADT/APFloat.h"
@@ -2905,7 +2906,8 @@ static void dumpProtocolConformanceRec(
29052906
break;
29062907

29072908
out << '\n';
2908-
conf->getSubstitutionMap().dump(out, indent + 2);
2909+
conf->getSubstitutionMap().dump(out, SubstitutionMap::DumpStyle::Full,
2910+
indent + 2);
29092911
out << '\n';
29102912
for (auto subReq : conf->getConditionalRequirements()) {
29112913
out.indent(indent + 2);
@@ -2939,27 +2941,33 @@ void ProtocolConformance::dump(llvm::raw_ostream &out, unsigned indent) const {
29392941
dumpProtocolConformanceRec(this, out, indent, visited);
29402942
}
29412943

2942-
void SubstitutionMap::dump(llvm::raw_ostream &out, unsigned indent) const {
2944+
void SubstitutionMap::dump(llvm::raw_ostream &out,
2945+
SubstitutionMap::DumpStyle style,
2946+
unsigned indent) const {
29432947
auto *genericSig = getGenericSignature();
29442948
out.indent(indent);
29452949

29462950
auto printParen = [&](char p) {
29472951
PrintWithColorRAII(out, ParenthesisColor) << p;
29482952
};
29492953
printParen('(');
2954+
SWIFT_DEFER { printParen(')'); };
29502955
out << "substitution_map generic_signature=";
29512956
if (genericSig == nullptr) {
29522957
out << "<nullptr>";
2953-
printParen(')');
29542958
return;
29552959
}
29562960

29572961
genericSig->print(out);
29582962
auto genericParams = genericSig->getGenericParams();
29592963
auto replacementTypes = getReplacementTypesBuffer();
29602964
for (unsigned i : indices(genericParams)) {
2961-
out << "\n";
2962-
out.indent(indent + 2);
2965+
if (style == SubstitutionMap::DumpStyle::Minimal) {
2966+
out << " ";
2967+
} else {
2968+
out << "\n";
2969+
out.indent(indent + 2);
2970+
}
29632971
printParen('(');
29642972
out << "substitution ";
29652973
genericParams[i]->print(out);
@@ -2970,6 +2978,10 @@ void SubstitutionMap::dump(llvm::raw_ostream &out, unsigned indent) const {
29702978
out << "<<unresolved concrete type>>";
29712979
printParen(')');
29722980
}
2981+
// A minimal dump doesn't need the details about the conformances, a lot of
2982+
// that info can be inferred from the signature.
2983+
if (style == SubstitutionMap::DumpStyle::Minimal)
2984+
return;
29732985

29742986
// We only really need to print a conformance once across this whole map.
29752987
llvm::SmallPtrSet<const ProtocolConformance *, 8> visited;

lib/AST/ConcreteDeclRef.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ void ConcreteDeclRef::dump(raw_ostream &os) {
5656
// If specialized, dump the substitutions.
5757
if (isSpecialized()) {
5858
os << " [with ";
59-
getSubstitutions().dump(os);
59+
getSubstitutions().dump(os, SubstitutionMap::DumpStyle::Minimal);
6060
os << ']';
6161
}
6262
}

test/Driver/dump-parse.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,10 @@ enum TrailingSemi {
5454
return y;
5555
};
5656
};
57+
58+
// The substitution map for a declref should be relatively unobtrustive.
59+
// CHECK-AST-LABEL: (func_decl "generic(_:)" <T : Hashable> interface type='<T where T : Hashable> (T) -> ()' access=internal captures=(<generic> )
60+
func generic<T: Hashable>(_: T) {}
61+
// CHECK-AST: (pattern_binding_decl
62+
// CHECK-AST: (declref_expr type='(Int) -> ()' location={{.*}} range={{.*}} decl=main.(file).generic@{{.*}} [with (substitution_map generic_signature=<T where T : Hashable> (substitution T -> Int))] function_ref=unapplied))
63+
let _: (Int) -> () = generic

0 commit comments

Comments
 (0)