diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 218d4c2fe4bbc..37a400682fdc9 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -5786,8 +5786,26 @@ class PrintConformance : public PrintBase { printField(conformance->getSourceKind(), Label::optional("source_kind")); printFlag(conformance->isRetroactive(), "retroactive"); printIsolation(conformance->getIsolation()); - if (!Writer.isParsable()) + + if (Writer.isParsable() && isTypeChecked()) { + // Print the decl context that declares the conformance, which should + // always be a type or extension declaration. Print the module as well, + // since an extension decl USR won't actually contain this if the + // module containing the conformance is different than the modules + // containing the type and the protocol. + printRecArbitrary([&](Label label) { + printHead("conformance_context", ASTNodeColor, label); + DeclContext *DC = conformance->getDeclContext(); + if (auto *D = DC->getAsDecl()) { + printField(declUSR(D), Label::always("decl")); + } + printField(DC->getParentModule()->getRealName(), + Label::always("module")); + printFoot(); + }, Label::always("context")); + } else { printFlag(!shouldPrintDetails, "
"); + } }; switch (conformance->getKind()) { @@ -5800,7 +5818,6 @@ class PrintConformance : public PrintBase { printFlag(normal->isPreconcurrencyEffectful(), "effectful_preconcurrency"); } - printFlag(normal->isRetroactive(), "retroactive"); printFlag(normal->isUnchecked(), "unchecked"); if (normal->getExplicitSafety() != ExplicitSafety::Unspecified) printField(normal->getExplicitSafety(), Label::always("safety")); @@ -5808,7 +5825,6 @@ class PrintConformance : public PrintBase { if (!shouldPrintDetails) break; - // Maybe print information about the conforming context? if (normal->isLazilyLoaded()) { printFlag("lazy"); } else { diff --git a/test/Frontend/ast-dump-json-conformance-context.swift b/test/Frontend/ast-dump-json-conformance-context.swift new file mode 100644 index 0000000000000..1cac17da2e882 --- /dev/null +++ b/test/Frontend/ast-dump-json-conformance-context.swift @@ -0,0 +1,52 @@ +// RUN: %empty-directory(%t) +// RUN: split-file %s %t +// RUN: %target-swift-frontend %t/SomeProtocolModule.swift -parse-as-library -emit-module -emit-module-path %t/SomeProtocolModule.swiftmodule -module-name SomeProtocolModule +// RUN: %target-swift-frontend %t/SomeTypeModule.swift -parse-as-library -emit-module -emit-module-path %t/SomeTypeModule.swiftmodule -module-name SomeTypeModule +// RUN: %target-swift-frontend %t/SomeTypeConformanceModule.swift -I %t -parse-as-library -emit-module -emit-module-path %t/SomeTypeConformanceModule.swiftmodule -module-name SomeTypeConformanceModule +// RUN: %target-swift-frontend %t/Client.swift -I %t -parse-as-library -dump-ast -dump-ast-format json -module-name Client -o - > %t/Client.json +// RUN: %{python} -c 'import json, sys; print(json.dumps(json.load(sys.stdin), indent=4))' < %t/Client.json | %FileCheck %s + +//--- SomeProtocolModule.swift +public protocol SomeProtocol {} + +//--- SomeTypeModule.swift +public struct SomeType { + public init() {} +} + +//--- SomeTypeConformanceModule.swift +import SomeProtocolModule +import SomeTypeModule + +extension SomeType: @retroactive SomeProtocol {} + +//--- Client.swift +import SomeProtocolModule +import SomeTypeConformanceModule +import SomeTypeModule + +func g(_ t: T) {} + +func f() { + g(SomeType()) +} + +// CHECK: "substitutions": { +// CHECK-NEXT: "_kind": "substitution_map", +// CHECK: "reqs": [ +// CHECK: { +// CHECK-NEXT: "_kind": "conformance", +// CHECK-NEXT: "type": "$sxD", +// CHECK-NEXT: "conformance": { +// CHECK-NEXT: "_kind": "normal_conformance", +// CHECK-NEXT: "type": "$s14SomeTypeModule0aB0VD", +// CHECK-NEXT: "protocol": "s:18SomeProtocolModule0aB0P", +// CHECK: "context": { +// CHECK-NEXT: "_kind": "conformance_context", +// CHECK-NEXT: "decl": "s:e:s:14SomeTypeModule0aB0Vs:18SomeProtocolModule0aB0P", +// CHECK-NEXT: "module": "SomeTypeConformanceModule" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }