@@ -200,6 +200,33 @@ class escaping_ostream : public raw_ostream {
200200 virtual void anchor () override {}
201201};
202202
203+ // / Replaces any local archetypes in the given type with their equivalent
204+ // / existential upper bounds so that they can be passed to the AST mangler. This
205+ // / loses information but is probably sufficient for most questions about these
206+ // / types that consumers of the JSON AST would ask.
207+ Type replaceLocalArchetypesWithExistentials (Type type) {
208+ return type.transformRec ([&](TypeBase *t) -> std::optional<Type> {
209+ if (auto LAT = dyn_cast<LocalArchetypeType>(t)) {
210+ return LAT->getExistentialType ();
211+ }
212+ return std::nullopt ;
213+ });
214+ }
215+
216+ // / Replaces any opaque type archetypes in the given type with their equivalent
217+ // / existential upper bounds. This is used when dumping the mapping of all
218+ // / opaque types in the source file so that their conformances can be more
219+ // / easily reasoned about without having to find the declaring opaque result
220+ // / type deeper in the AST.
221+ Type replaceOpaqueArchetypesWithExistentials (Type type) {
222+ return type.transformRec ([&](TypeBase *t) -> std::optional<Type> {
223+ if (auto OT = dyn_cast<OpaqueTypeArchetypeType>(t)) {
224+ return OT->getExistentialType ();
225+ }
226+ return std::nullopt ;
227+ });
228+ }
229+
203230// / Returns the USR of the given declaration. Gracefully returns an empty
204231// / string if D is null or invalid.
205232std::string declUSR (const Decl *D) {
@@ -234,14 +261,10 @@ std::string typeUSR(Type type) {
234261 return " " ;
235262
236263 if (type->hasArchetype ()) {
237- // We can't generate USRs for types that contain archetypes. Replace them
238- // with their interface types.
239- type = type.transformRec ([&](TypeBase *t) -> std::optional<Type> {
240- if (auto AT = dyn_cast<ArchetypeType>(t)) {
241- return AT->getInterfaceType ();
242- }
243- return std::nullopt ;
244- });
264+ type = type->mapTypeOutOfContext ();
265+ }
266+ if (type->hasLocalArchetype ()) {
267+ type = replaceLocalArchetypesWithExistentials (type);
245268 }
246269
247270 std::string usr;
@@ -628,6 +651,21 @@ static StringRef getDumpString(ExplicitSafety safety) {
628651 return " unsafe" ;
629652 }
630653}
654+ static StringRef getDumpString (ConformanceEntryKind kind) {
655+ switch (kind) {
656+ case ConformanceEntryKind::Inherited:
657+ return " inherited" ;
658+ case ConformanceEntryKind::Explicit:
659+ return " explicit" ;
660+ case ConformanceEntryKind::PreMacroExpansion:
661+ return " pre_macro_expansion" ;
662+ case ConformanceEntryKind::Synthesized:
663+ return " synthesized" ;
664+ case ConformanceEntryKind::Implied:
665+ return " implied" ;
666+ }
667+ llvm_unreachable (" unhandled ConformanceEntryKind" );
668+ }
631669static StringRef getDumpString (StringRef s) {
632670 return s;
633671}
@@ -1251,6 +1289,40 @@ namespace {
12511289 void printRec (const ProtocolConformance *conformance,
12521290 VisitedConformances &visited, Label label);
12531291
1292+ // Print a field that describes the actor isolation associated with an AST
1293+ // node.
1294+ void printIsolation (const ActorIsolation &isolation) {
1295+ switch (isolation) {
1296+ case ActorIsolation::Unspecified:
1297+ case ActorIsolation::NonisolatedUnsafe:
1298+ break ;
1299+
1300+ case ActorIsolation::Nonisolated:
1301+ printFlag (true , " nonisolated" , CapturesColor);
1302+ break ;
1303+
1304+ case ActorIsolation::Erased:
1305+ printFlag (true , " dynamically_isolated" , CapturesColor);
1306+ break ;
1307+
1308+ case ActorIsolation::CallerIsolationInheriting:
1309+ printFlag (true , " isolated_to_caller_isolation" , CapturesColor);
1310+ break ;
1311+
1312+ case ActorIsolation::ActorInstance:
1313+ printReferencedDeclWithContextField (isolation.getActorInstance (),
1314+ Label::always (" actor_isolated" ),
1315+ CapturesColor);
1316+ break ;
1317+
1318+ case ActorIsolation::GlobalActor:
1319+ printTypeField (isolation.getGlobalActor (),
1320+ Label::always (" global_actor_isolated" ), PrintOptions (),
1321+ CapturesColor);
1322+ break ;
1323+ }
1324+ }
1325+
12541326 // / Print a requirement node.
12551327 void visitRequirement (const Requirement &requirement, Label label) {
12561328 printHead (" requirement" , ASTNodeColor, label);
@@ -1262,13 +1334,19 @@ namespace {
12621334
12631335 printField (requirement.getKind (), Label::optional (" kind" ));
12641336
1265- if (requirement.getKind () != RequirementKind::Layout
1266- && requirement.getSecondType ())
1267- printTypeField (requirement.getSecondType (),
1268- Label::optional (" second_type" ), opts);
1269- else if (requirement.getLayoutConstraint ())
1337+ switch (requirement.getKind ()) {
1338+ case RequirementKind::Layout:
12701339 printFieldQuoted (requirement.getLayoutConstraint (),
12711340 Label::optional (" layout" ));
1341+ break ;
1342+ case RequirementKind::Conformance:
1343+ printReferencedDeclField (requirement.getProtocolDecl (),
1344+ Label::optional (" protocol" ));
1345+ break ;
1346+ default :
1347+ printTypeField (requirement.getSecondType (),
1348+ Label::optional (" second_type" ), opts);
1349+ }
12721350
12731351 printFoot ();
12741352 }
@@ -1917,6 +1995,62 @@ namespace {
19171995 }
19181996 }
19191997
1998+ void printInheritance (const IterableDeclContext *DC) {
1999+ if (!(Writer.isParsable () && isTypeChecked ())) {
2000+ // If the output is not parsable or we're not type-checked, just print
2001+ // the inheritance list as written.
2002+ switch (DC->getIterableContextKind ()) {
2003+ case IterableDeclContextKind::NominalTypeDecl:
2004+ printInherited (cast<NominalTypeDecl>(DC)->getInherited ());
2005+ break ;
2006+ case IterableDeclContextKind::ExtensionDecl:
2007+ printInherited (cast<ExtensionDecl>(DC)->getInherited ());
2008+ break ;
2009+ }
2010+ return ;
2011+ }
2012+
2013+ // For parsable, type-checked output, print a more structured
2014+ // representation of the data.
2015+ printRecArbitrary (
2016+ [&](Label label) {
2017+ printHead (" inheritance" , FieldLabelColor, label);
2018+
2019+ SmallPtrSet<const ProtocolConformance *, 4 > dumped;
2020+ printList (
2021+ DC->getLocalConformances (),
2022+ [&](auto conformance, Label label) {
2023+ printRec (conformance, dumped, label);
2024+ },
2025+ Label::always (" conformances" ));
2026+
2027+ if (auto CD = dyn_cast<ClassDecl>(DC); CD && CD->hasSuperclass ()) {
2028+ printTypeField (CD->getSuperclass (),
2029+ Label::always (" superclass_type" ));
2030+ }
2031+
2032+ if (auto ED = dyn_cast<EnumDecl>(DC); ED && ED->hasRawType ()) {
2033+ printTypeField (ED->getRawType (), Label::always (" raw_type" ));
2034+ }
2035+
2036+ if (auto PD = dyn_cast<ProtocolDecl>(DC)) {
2037+ printList (
2038+ PD->getAllInheritedProtocols (),
2039+ [&](auto inherited, Label label) {
2040+ printReferencedDeclField (inherited, label);
2041+ },
2042+ Label::always (" protocols" ));
2043+ if (PD->hasSuperclass ()) {
2044+ printReferencedDeclField (PD->getSuperclassDecl (),
2045+ Label::always (" superclass_decl_usr" ));
2046+ }
2047+ }
2048+
2049+ printFoot ();
2050+ },
2051+ Label::always (" inherits" ));
2052+ }
2053+
19202054 void printInherited (InheritedTypes Inherited) {
19212055 if (Writer.isParsable ()) {
19222056 printList (
@@ -2252,13 +2386,13 @@ namespace {
22522386 switch (IDC->getIterableContextKind ()) {
22532387 case IterableDeclContextKind::NominalTypeDecl: {
22542388 const auto NTD = cast<NominalTypeDecl>(IDC);
2255- printInherited (NTD-> getInherited () );
2389+ printInheritance (NTD);
22562390 printWhereRequirements (NTD);
22572391 break ;
22582392 }
22592393 case IterableDeclContextKind::ExtensionDecl:
22602394 const auto ED = cast<ExtensionDecl>(IDC);
2261- printInherited (ED-> getInherited () );
2395+ printInheritance (ED);
22622396 printWhereRequirements (ED);
22632397 break ;
22642398 }
@@ -2289,6 +2423,27 @@ namespace {
22892423 printFoot ();
22902424 }
22912425
2426+ // Prints a mapping from the declared interface types of the opaque types to
2427+ // their equivalent existential type. This loses some information, but it is
2428+ // meant to make it easier to determine which protocols an opaque type
2429+ // conforms to when such a type appears elsewhere in an expression dump,
2430+ // farther away from where the opaque type is declared.
2431+ void printOpaqueTypeMapping (ArrayRef<OpaqueTypeDecl *> opaqueDecls) {
2432+ printRecArbitrary (
2433+ [&](Label label) {
2434+ printHead (" opaque_to_existential_mapping" , FieldLabelColor, label);
2435+ for (const auto OTD : opaqueDecls) {
2436+ Type interfaceType = OTD->getDeclaredInterfaceType ();
2437+ Type existentialType =
2438+ replaceOpaqueArchetypesWithExistentials (interfaceType);
2439+ printTypeField (existentialType,
2440+ Label::always (typeUSR (interfaceType)));
2441+ }
2442+ printFoot ();
2443+ },
2444+ Label::always (" opaque_to_existential_mapping" ));
2445+ }
2446+
22922447 void visitSourceFile (const SourceFile &SF) {
22932448 Writer.setMainBufferID (SF.getBufferID ());
22942449
@@ -2357,6 +2512,15 @@ namespace {
23572512 }
23582513 },
23592514 Label::optional (" items" ));
2515+
2516+ if (Writer.isParsable () && isTypeChecked ()) {
2517+ SmallVector<OpaqueTypeDecl *, 4 > opaqueDecls;
2518+ SF.getOpaqueReturnTypeDecls (opaqueDecls);
2519+ if (!opaqueDecls.empty ()) {
2520+ printOpaqueTypeMapping (opaqueDecls);
2521+ }
2522+ }
2523+
23602524 printFoot ();
23612525 }
23622526
@@ -3941,36 +4105,7 @@ class PrintExpr : public ExprVisitor<PrintExpr, void, Label>,
39414105
39424106 printField (E->getRawDiscriminator (), Label::always (" discriminator" ),
39434107 DiscriminatorColor);
3944-
3945- switch (auto isolation = E->getActorIsolation ()) {
3946- case ActorIsolation::Unspecified:
3947- case ActorIsolation::NonisolatedUnsafe:
3948- break ;
3949-
3950- case ActorIsolation::Nonisolated:
3951- printFlag (true , " nonisolated" , CapturesColor);
3952- break ;
3953-
3954- case ActorIsolation::Erased:
3955- printFlag (true , " dynamically_isolated" , CapturesColor);
3956- break ;
3957-
3958- case ActorIsolation::CallerIsolationInheriting:
3959- printFlag (true , " isolated_to_caller_isolation" , CapturesColor);
3960- break ;
3961-
3962- case ActorIsolation::ActorInstance:
3963- printReferencedDeclWithContextField (isolation.getActorInstance (),
3964- Label::always (" actor_isolated" ),
3965- CapturesColor);
3966- break ;
3967-
3968- case ActorIsolation::GlobalActor:
3969- printTypeField (isolation.getGlobalActor (),
3970- Label::always (" global_actor_isolated" ), PrintOptions (),
3971- CapturesColor);
3972- break ;
3973- }
4108+ printIsolation (E->getActorIsolation ());
39744109
39754110 if (auto captureInfo = E->getCachedCaptureInfo ()) {
39764111 printCaptureInfoField (captureInfo, Label::optional (" captures" ));
@@ -5552,6 +5687,9 @@ class PrintConformance : public PrintBase {
55525687 printTypeField (conformance->getType (), Label::always (" type" ));
55535688 printReferencedDeclField (conformance->getProtocol (),
55545689 Label::always (" protocol" ));
5690+ printField (conformance->getSourceKind (), Label::optional (" source_kind" ));
5691+ printFlag (conformance->isRetroactive (), " retroactive" );
5692+ printIsolation (conformance->getIsolation ());
55555693 if (!Writer.isParsable ())
55565694 printFlag (!shouldPrintDetails, " <details printed above>" );
55575695 };
@@ -5561,6 +5699,16 @@ class PrintConformance : public PrintBase {
55615699 auto normal = cast<NormalProtocolConformance>(conformance);
55625700
55635701 printCommon (" normal_conformance" );
5702+ printFlag (normal->isPreconcurrency (), " preconcurrency" );
5703+ if (normal->isPreconcurrency () && normal->isComplete ()) {
5704+ printFlag (normal->isPreconcurrencyEffectful (),
5705+ " effectful_preconcurrency" );
5706+ }
5707+ printFlag (normal->isRetroactive (), " retroactive" );
5708+ printFlag (normal->isUnchecked (), " unchecked" );
5709+ if (normal->getExplicitSafety () != ExplicitSafety::Unspecified)
5710+ printField (normal->getExplicitSafety (), Label::always (" safety" ));
5711+
55645712 if (!shouldPrintDetails)
55655713 break ;
55665714
@@ -5775,27 +5923,33 @@ class PrintConformance : public PrintBase {
57755923
57765924void PrintBase::printRec (SubstitutionMap map, VisitedConformances &visited,
57775925 Label label) {
5778- printRecArbitrary ([&](Label label) {
5779- PrintConformance (Writer)
5780- .visitSubstitutionMap (map, SubstitutionMap::DumpStyle::Full, visited,
5781- label);
5782- }, label);
5926+ printRecArbitrary (
5927+ [&](Label label) {
5928+ PrintConformance (Writer, MemberLoading)
5929+ .visitSubstitutionMap (map, SubstitutionMap::DumpStyle::Full,
5930+ visited, label);
5931+ },
5932+ label);
57835933}
57845934
57855935void PrintBase::printRec (const ProtocolConformanceRef &ref,
57865936 VisitedConformances &visited, Label label) {
5787- printRecArbitrary ([&](Label label) {
5788- PrintConformance (Writer)
5789- .visitProtocolConformanceRef (ref, visited, label);
5790- }, label);
5937+ printRecArbitrary (
5938+ [&](Label label) {
5939+ PrintConformance (Writer, MemberLoading)
5940+ .visitProtocolConformanceRef (ref, visited, label);
5941+ },
5942+ label);
57915943}
57925944
57935945void PrintBase::printRec (const ProtocolConformance *conformance,
57945946 VisitedConformances &visited, Label label) {
5795- printRecArbitrary ([&](Label label) {
5796- PrintConformance (Writer)
5797- .visitProtocolConformance (conformance, visited, label);
5798- }, label);
5947+ printRecArbitrary (
5948+ [&](Label label) {
5949+ PrintConformance (Writer, MemberLoading)
5950+ .visitProtocolConformance (conformance, visited, label);
5951+ },
5952+ label);
57995953}
58005954
58015955} // end anonymous namespace
0 commit comments