@@ -200,6 +200,33 @@ class escaping_ostream : public raw_ostream {
200
200
virtual void anchor () override {}
201
201
};
202
202
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
+
203
230
// / Returns the USR of the given declaration. Gracefully returns an empty
204
231
// / string if D is null or invalid.
205
232
std::string declUSR (const Decl *D) {
@@ -234,14 +261,10 @@ std::string typeUSR(Type type) {
234
261
return " " ;
235
262
236
263
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);
245
268
}
246
269
247
270
std::string usr;
@@ -628,6 +651,21 @@ static StringRef getDumpString(ExplicitSafety safety) {
628
651
return " unsafe" ;
629
652
}
630
653
}
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
+ }
631
669
static StringRef getDumpString (StringRef s) {
632
670
return s;
633
671
}
@@ -1251,6 +1289,40 @@ namespace {
1251
1289
void printRec (const ProtocolConformance *conformance,
1252
1290
VisitedConformances &visited, Label label);
1253
1291
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
+
1254
1326
// / Print a requirement node.
1255
1327
void visitRequirement (const Requirement &requirement, Label label) {
1256
1328
printHead (" requirement" , ASTNodeColor, label);
@@ -1262,13 +1334,19 @@ namespace {
1262
1334
1263
1335
printField (requirement.getKind (), Label::optional (" kind" ));
1264
1336
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:
1270
1339
printFieldQuoted (requirement.getLayoutConstraint (),
1271
1340
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
+ }
1272
1350
1273
1351
printFoot ();
1274
1352
}
@@ -1917,6 +1995,62 @@ namespace {
1917
1995
}
1918
1996
}
1919
1997
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
+
1920
2054
void printInherited (InheritedTypes Inherited) {
1921
2055
if (Writer.isParsable ()) {
1922
2056
printList (
@@ -2252,13 +2386,13 @@ namespace {
2252
2386
switch (IDC->getIterableContextKind ()) {
2253
2387
case IterableDeclContextKind::NominalTypeDecl: {
2254
2388
const auto NTD = cast<NominalTypeDecl>(IDC);
2255
- printInherited (NTD-> getInherited () );
2389
+ printInheritance (NTD);
2256
2390
printWhereRequirements (NTD);
2257
2391
break ;
2258
2392
}
2259
2393
case IterableDeclContextKind::ExtensionDecl:
2260
2394
const auto ED = cast<ExtensionDecl>(IDC);
2261
- printInherited (ED-> getInherited () );
2395
+ printInheritance (ED);
2262
2396
printWhereRequirements (ED);
2263
2397
break ;
2264
2398
}
@@ -2289,6 +2423,27 @@ namespace {
2289
2423
printFoot ();
2290
2424
}
2291
2425
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
+
2292
2447
void visitSourceFile (const SourceFile &SF) {
2293
2448
Writer.setMainBufferID (SF.getBufferID ());
2294
2449
@@ -2357,6 +2512,15 @@ namespace {
2357
2512
}
2358
2513
},
2359
2514
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
+
2360
2524
printFoot ();
2361
2525
}
2362
2526
@@ -3941,36 +4105,7 @@ class PrintExpr : public ExprVisitor<PrintExpr, void, Label>,
3941
4105
3942
4106
printField (E->getRawDiscriminator (), Label::always (" discriminator" ),
3943
4107
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 ());
3974
4109
3975
4110
if (auto captureInfo = E->getCachedCaptureInfo ()) {
3976
4111
printCaptureInfoField (captureInfo, Label::optional (" captures" ));
@@ -5551,6 +5686,9 @@ class PrintConformance : public PrintBase {
5551
5686
printTypeField (conformance->getType (), Label::always (" type" ));
5552
5687
printReferencedDeclField (conformance->getProtocol (),
5553
5688
Label::always (" protocol" ));
5689
+ printField (conformance->getSourceKind (), Label::optional (" source_kind" ));
5690
+ printFlag (conformance->isRetroactive (), " retroactive" );
5691
+ printIsolation (conformance->getIsolation ());
5554
5692
if (!Writer.isParsable ())
5555
5693
printFlag (!shouldPrintDetails, " <details printed above>" );
5556
5694
};
@@ -5560,6 +5698,16 @@ class PrintConformance : public PrintBase {
5560
5698
auto normal = cast<NormalProtocolConformance>(conformance);
5561
5699
5562
5700
printCommon (" normal_conformance" );
5701
+ printFlag (normal->isPreconcurrency (), " preconcurrency" );
5702
+ if (normal->isPreconcurrency () && normal->isComplete ()) {
5703
+ printFlag (normal->isPreconcurrencyEffectful (),
5704
+ " effectful_preconcurrency" );
5705
+ }
5706
+ printFlag (normal->isRetroactive (), " retroactive" );
5707
+ printFlag (normal->isUnchecked (), " unchecked" );
5708
+ if (normal->getExplicitSafety () != ExplicitSafety::Unspecified)
5709
+ printField (normal->getExplicitSafety (), Label::always (" safety" ));
5710
+
5563
5711
if (!shouldPrintDetails)
5564
5712
break ;
5565
5713
@@ -5774,27 +5922,33 @@ class PrintConformance : public PrintBase {
5774
5922
5775
5923
void PrintBase::printRec (SubstitutionMap map, VisitedConformances &visited,
5776
5924
Label label) {
5777
- printRecArbitrary ([&](Label label) {
5778
- PrintConformance (Writer)
5779
- .visitSubstitutionMap (map, SubstitutionMap::DumpStyle::Full, visited,
5780
- label);
5781
- }, label);
5925
+ printRecArbitrary (
5926
+ [&](Label label) {
5927
+ PrintConformance (Writer, MemberLoading)
5928
+ .visitSubstitutionMap (map, SubstitutionMap::DumpStyle::Full,
5929
+ visited, label);
5930
+ },
5931
+ label);
5782
5932
}
5783
5933
5784
5934
void PrintBase::printRec (const ProtocolConformanceRef &ref,
5785
5935
VisitedConformances &visited, Label label) {
5786
- printRecArbitrary ([&](Label label) {
5787
- PrintConformance (Writer)
5788
- .visitProtocolConformanceRef (ref, visited, label);
5789
- }, label);
5936
+ printRecArbitrary (
5937
+ [&](Label label) {
5938
+ PrintConformance (Writer, MemberLoading)
5939
+ .visitProtocolConformanceRef (ref, visited, label);
5940
+ },
5941
+ label);
5790
5942
}
5791
5943
5792
5944
void PrintBase::printRec (const ProtocolConformance *conformance,
5793
5945
VisitedConformances &visited, Label label) {
5794
- printRecArbitrary ([&](Label label) {
5795
- PrintConformance (Writer)
5796
- .visitProtocolConformance (conformance, visited, label);
5797
- }, label);
5946
+ printRecArbitrary (
5947
+ [&](Label label) {
5948
+ PrintConformance (Writer, MemberLoading)
5949
+ .visitProtocolConformance (conformance, visited, label);
5950
+ },
5951
+ label);
5798
5952
}
5799
5953
5800
5954
} // end anonymous namespace
0 commit comments