|
23 | 23 | #include "swift/AST/Module.h" |
24 | 24 | #include "swift/AST/ParameterList.h" |
25 | 25 | #include "swift/AST/ProtocolConformance.h" |
| 26 | +#include "swift/AST/ProtocolConformanceRef.h" |
| 27 | +#include "swift/Basic/Defer.h" |
26 | 28 | #include "swift/Demangling/ManglingUtils.h" |
27 | 29 | #include "swift/Demangling/Demangler.h" |
28 | 30 | #include "swift/Strings.h" |
@@ -856,6 +858,7 @@ void ASTMangler::appendType(Type type) { |
856 | 858 | appendAnyGenericType(NDecl); |
857 | 859 | bool isFirstArgList = true; |
858 | 860 | appendBoundGenericArgs(type, isFirstArgList); |
| 861 | + appendRetroactiveConformances(type); |
859 | 862 | appendOperator("G"); |
860 | 863 | } |
861 | 864 | addSubstitution(type.getPointer()); |
@@ -1088,6 +1091,44 @@ void ASTMangler::appendBoundGenericArgs(Type type, bool &isFirstArgList) { |
1088 | 1091 | } |
1089 | 1092 | } |
1090 | 1093 |
|
| 1094 | +void ASTMangler::appendRetroactiveConformances(Type type) { |
| 1095 | + auto nominal = type->getAnyNominal(); |
| 1096 | + if (!nominal) return; |
| 1097 | + |
| 1098 | + auto genericSig = nominal->getGenericSignatureOfContext(); |
| 1099 | + if (!genericSig) return; |
| 1100 | + |
| 1101 | + auto module = Mod ? Mod : nominal->getModuleContext(); |
| 1102 | + auto subMap = type->getContextSubstitutionMap(module, nominal); |
| 1103 | + if (subMap.empty()) return; |
| 1104 | + |
| 1105 | + unsigned numProtocolRequirements = 0; |
| 1106 | + for (const auto &req: genericSig->getRequirements()) { |
| 1107 | + if (req.getKind() != RequirementKind::Conformance) |
| 1108 | + continue; |
| 1109 | + |
| 1110 | + SWIFT_DEFER { |
| 1111 | + ++numProtocolRequirements; |
| 1112 | + }; |
| 1113 | + |
| 1114 | + // Fast path: we're in the module of the protocol. |
| 1115 | + auto proto = req.getSecondType()->castTo<ProtocolType>()->getDecl(); |
| 1116 | + if (proto->getModuleContext() == module) |
| 1117 | + continue; |
| 1118 | + |
| 1119 | + auto conformance = |
| 1120 | + subMap.lookupConformance(req.getFirstType()->getCanonicalType(), proto); |
| 1121 | + if (!conformance || !conformance->isConcrete()) continue; |
| 1122 | + |
| 1123 | + auto normal = conformance->getConcrete()->getRootNormalConformance(); |
| 1124 | + if (!normal->isRetroactive() || normal->isSynthesizedNonUnique()) |
| 1125 | + continue; |
| 1126 | + |
| 1127 | + appendProtocolConformance(normal); |
| 1128 | + appendOperator("g", Index(numProtocolRequirements)); |
| 1129 | + } |
| 1130 | +} |
| 1131 | + |
1091 | 1132 | static char getParamConvention(ParameterConvention conv) { |
1092 | 1133 | // @in and @out are mangled the same because they're put in |
1093 | 1134 | // different places. |
|
0 commit comments