@@ -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) {
@@ -237,15 +264,7 @@ std::string typeUSR(Type type) {
237264 type = type->mapTypeOutOfContext ();
238265 }
239266 if (type->hasLocalArchetype ()) {
240- // If we have local archetypes, we can't mangle those. Replace them with
241- // their existential upper bounds, which loses information but is probably
242- // close enough for most purposes.
243- type = type.transformRec ([&](TypeBase *t) -> std::optional<Type> {
244- if (auto LAT = dyn_cast<LocalArchetypeType>(t)) {
245- return LAT->getExistentialType ();
246- }
247- return std::nullopt ;
248- });
267+ type = replaceLocalArchetypesWithExistentials (type);
249268 }
250269
251270 std::string usr;
@@ -1323,27 +1342,19 @@ namespace {
13231342
13241343 printField (requirement.getKind (), Label::optional (" kind" ));
13251344
1326- if (requirement.getKind () != RequirementKind::Layout &&
1327- requirement.getSecondType ()) {
1328- if (Writer.isParsable ()) {
1329- // If this is a conformance requirement, print the USR of the protocol
1330- // decl instead of the type. The type USR for a protocol is based on
1331- // the equivalent expanded existential, which drops suppressed
1332- // protocols.
1333- if (requirement.getKind () == RequirementKind::Conformance) {
1334- printReferencedDeclField (requirement.getProtocolDecl (),
1335- Label::optional (" protocol" ));
1336- } else {
1337- printTypeField (requirement.getSecondType (),
1338- Label::optional (" second_type" ), opts);
1339- }
1340- } else {
1341- printTypeField (requirement.getSecondType (),
1342- Label::optional (" second_type" ), opts);
1343- }
1344- } else if (requirement.getLayoutConstraint ())
1345+ switch (requirement.getKind ()) {
1346+ case RequirementKind::Layout:
13451347 printFieldQuoted (requirement.getLayoutConstraint (),
13461348 Label::optional (" layout" ));
1349+ break ;
1350+ case RequirementKind::Conformance:
1351+ printReferencedDeclField (requirement.getProtocolDecl (),
1352+ Label::optional (" protocol" ));
1353+ break ;
1354+ default :
1355+ printTypeField (requirement.getSecondType (),
1356+ Label::optional (" second_type" ), opts);
1357+ }
13471358
13481359 printFoot ();
13491360 }
@@ -2022,8 +2033,8 @@ namespace {
20222033 Label::always (" conformances" ));
20232034
20242035 if (auto CD = dyn_cast<ClassDecl>(DC); CD && CD->hasSuperclass ()) {
2025- printReferencedDeclField (CD->getSuperclassDecl (),
2026- Label::always (" superclass_decl_usr " ));
2036+ printTypeField (CD->getSuperclass (),
2037+ Label::always (" superclass_type " ));
20272038 }
20282039
20292040 if (auto ED = dyn_cast<EnumDecl>(DC); ED && ED->hasRawType ()) {
@@ -2432,8 +2443,7 @@ namespace {
24322443 for (const auto OTD : opaqueDecls) {
24332444 Type interfaceType = OTD->getDeclaredInterfaceType ();
24342445 Type existentialType =
2435- interfaceType->castTo <OpaqueTypeArchetypeType>()
2436- ->getExistentialType ();
2446+ replaceOpaqueArchetypesWithExistentials (interfaceType);
24372447 printTypeField (existentialType,
24382448 Label::always (typeUSR (interfaceType)));
24392449 }
0 commit comments