@@ -2420,6 +2420,28 @@ namespace {
24202420 printFoot ();
24212421 }
24222422
2423+ // Prints a mapping from the declared interface types of the opaque types to
2424+ // their equivalent existential type. This loses some information, but it is
2425+ // meant to make it easier to determine which protocols an opaque type
2426+ // conforms to when such a type appears elsewhere in an expression dump,
2427+ // farther away from where the opaque type is declared.
2428+ void printOpaqueTypeMapping (ArrayRef<OpaqueTypeDecl *> opaqueDecls) {
2429+ printRecArbitrary (
2430+ [&](Label label) {
2431+ printHead (" opaque_to_existential_mapping" , FieldLabelColor, label);
2432+ for (const auto OTD : opaqueDecls) {
2433+ Type interfaceType = OTD->getDeclaredInterfaceType ();
2434+ Type existentialType =
2435+ interfaceType->castTo <OpaqueTypeArchetypeType>()
2436+ ->getExistentialType ();
2437+ printTypeField (existentialType,
2438+ Label::always (typeUSR (interfaceType)));
2439+ }
2440+ printFoot ();
2441+ },
2442+ Label::always (" opaque_to_existential_mapping" ));
2443+ }
2444+
24232445 void visitSourceFile (const SourceFile &SF) {
24242446 Writer.setMainBufferID (SF.getBufferID ());
24252447
@@ -2488,6 +2510,15 @@ namespace {
24882510 }
24892511 },
24902512 Label::optional (" items" ));
2513+
2514+ if (Writer.isParsable () && isTypeChecked ()) {
2515+ SmallVector<OpaqueTypeDecl *, 4 > opaqueDecls;
2516+ SF.getOpaqueReturnTypeDecls (opaqueDecls);
2517+ if (!opaqueDecls.empty ()) {
2518+ printOpaqueTypeMapping (opaqueDecls);
2519+ }
2520+ }
2521+
24912522 printFoot ();
24922523 }
24932524
0 commit comments