@@ -489,6 +489,8 @@ class TypeSubstituter : public TypeTransform<TypeSubstituter> {
489
489
: level(level), IFS(IFS) {}
490
490
491
491
std::optional<Type> transform (TypeBase *type, TypePosition position);
492
+
493
+ SubstitutionMap transformSubstitutionMap (SubstitutionMap subs);
492
494
};
493
495
494
496
}
@@ -624,6 +626,11 @@ TypeSubstituter::transform(TypeBase *type, TypePosition position) {
624
626
level);
625
627
}
626
628
629
+ SubstitutionMap TypeSubstituter::transformSubstitutionMap (SubstitutionMap subs) {
630
+ // FIXME: Take level into account? Move level down into IFS?
631
+ return subs.subst (IFS);
632
+ }
633
+
627
634
Type Type::subst (SubstitutionMap substitutions,
628
635
SubstOptions options) const {
629
636
InFlightSubstitutionViaSubMap IFS (substitutions, options);
@@ -1038,18 +1045,6 @@ Type TypeBase::adjustSuperclassMemberDeclType(const ValueDecl *baseDecl,
1038
1045
// Replacing opaque result archetypes with their underlying types
1039
1046
// ===----------------------------------------------------------------------===//
1040
1047
1041
- static std::optional<std::pair<ArchetypeType *, OpaqueTypeArchetypeType *>>
1042
- getArchetypeAndRootOpaqueArchetype (Type maybeOpaqueType) {
1043
- auto archetype = dyn_cast<ArchetypeType>(maybeOpaqueType.getPointer ());
1044
- if (!archetype)
1045
- return std::nullopt ;
1046
- auto opaqueRoot = dyn_cast<OpaqueTypeArchetypeType>(archetype->getRoot ());
1047
- if (!opaqueRoot)
1048
- return std::nullopt ;
1049
-
1050
- return std::make_pair (archetype, opaqueRoot);
1051
- }
1052
-
1053
1048
OpaqueSubstitutionKind
1054
1049
ReplaceOpaqueTypesWithUnderlyingTypes::shouldPerformSubstitution (
1055
1050
OpaqueTypeDecl *opaque) const {
@@ -1187,19 +1182,20 @@ ReplaceOpaqueTypesWithUnderlyingTypes::ReplaceOpaqueTypesWithUnderlyingTypes(
1187
1182
1188
1183
Type ReplaceOpaqueTypesWithUnderlyingTypes::
1189
1184
operator ()(SubstitutableType *maybeOpaqueType) const {
1190
- auto archetypeAndRoot = getArchetypeAndRootOpaqueArchetype (maybeOpaqueType);
1191
- if (!archetypeAndRoot )
1185
+ auto *archetype = dyn_cast<OpaqueTypeArchetypeType> (maybeOpaqueType);
1186
+ if (!archetype )
1192
1187
return maybeOpaqueType;
1193
1188
1194
- auto archetype = archetypeAndRoot->first ;
1195
- auto opaqueRoot = archetypeAndRoot->second ;
1189
+ auto *genericEnv = archetype->getGenericEnvironment ();
1190
+ auto *decl = genericEnv->getOpaqueTypeDecl ();
1191
+ auto outerSubs = genericEnv->getOpaqueSubstitutions ();
1196
1192
1197
- auto substitutionKind = shouldPerformSubstitution (opaqueRoot-> getDecl () );
1193
+ auto substitutionKind = shouldPerformSubstitution (decl );
1198
1194
if (substitutionKind == OpaqueSubstitutionKind::DontSubstitute) {
1199
1195
return maybeOpaqueType;
1200
1196
}
1201
1197
1202
- auto subs = opaqueRoot-> getDecl () ->getUniqueUnderlyingTypeSubstitutions ();
1198
+ auto subs = decl ->getUniqueUnderlyingTypeSubstitutions ();
1203
1199
// If the body of the opaque decl providing decl has not been type checked we
1204
1200
// don't have a underlying substitution.
1205
1201
if (!subs.has_value ())
@@ -1231,11 +1227,11 @@ operator()(SubstitutableType *maybeOpaqueType) const {
1231
1227
// for its type arguments. We perform this substitution after checking for
1232
1228
// visibility, since we do not want the result of the visibility check to
1233
1229
// depend on the substitutions previously applied.
1234
- auto substTy = partialSubstTy.subst (opaqueRoot-> getSubstitutions () );
1230
+ auto substTy = partialSubstTy.subst (outerSubs );
1235
1231
1236
1232
// If the type changed, but still contains opaque types, recur.
1237
1233
if (!substTy->isEqual (maybeOpaqueType) && substTy->hasOpaqueArchetype ()) {
1238
- SeenDecl seenKey (opaqueRoot-> getDecl (), opaqueRoot-> getSubstitutions () );
1234
+ SeenDecl seenKey (decl, outerSubs );
1239
1235
if (auto *alreadySeen = this ->seenDecls ) {
1240
1236
// Detect substitution loops. If we find one, just bounce the original
1241
1237
// type back to the caller. This substitution will fail at runtime
@@ -1305,8 +1301,8 @@ operator()(CanType maybeOpaqueType, Type replacementType,
1305
1301
ProtocolDecl *protocol) const {
1306
1302
auto abstractRef = ProtocolConformanceRef (protocol);
1307
1303
1308
- auto archetypeAndRoot = getArchetypeAndRootOpaqueArchetype (maybeOpaqueType);
1309
- if (!archetypeAndRoot ) {
1304
+ auto archetype = dyn_cast<OpaqueTypeArchetypeType> (maybeOpaqueType);
1305
+ if (!archetype ) {
1310
1306
if (maybeOpaqueType->isTypeParameter () ||
1311
1307
maybeOpaqueType->is <ArchetypeType>())
1312
1308
return abstractRef;
@@ -1320,15 +1316,16 @@ operator()(CanType maybeOpaqueType, Type replacementType,
1320
1316
llvm_unreachable (" origType should have been an opaque type or type parameter" );
1321
1317
}
1322
1318
1323
- auto archetype = archetypeAndRoot->first ;
1324
- auto opaqueRoot = archetypeAndRoot->second ;
1319
+ auto *genericEnv = archetype->getGenericEnvironment ();
1320
+ auto *decl = genericEnv->getOpaqueTypeDecl ();
1321
+ auto outerSubs = genericEnv->getOpaqueSubstitutions ();
1325
1322
1326
- auto substitutionKind = shouldPerformSubstitution (opaqueRoot-> getDecl () );
1323
+ auto substitutionKind = shouldPerformSubstitution (decl );
1327
1324
if (substitutionKind == OpaqueSubstitutionKind::DontSubstitute) {
1328
1325
return abstractRef;
1329
1326
}
1330
1327
1331
- auto subs = opaqueRoot-> getDecl () ->getUniqueUnderlyingTypeSubstitutions ();
1328
+ auto subs = decl ->getUniqueUnderlyingTypeSubstitutions ();
1332
1329
// If the body of the opaque decl providing decl has not been type checked we
1333
1330
// don't have a underlying substitution.
1334
1331
if (!subs.has_value ())
@@ -1359,16 +1356,16 @@ operator()(CanType maybeOpaqueType, Type replacementType,
1359
1356
// for its type arguments. We perform this substitution after checking for
1360
1357
// visibility, since we do not want the result of the visibility check to
1361
1358
// depend on the substitutions previously applied.
1362
- auto substTy = partialSubstTy.subst (opaqueRoot-> getSubstitutions () );
1359
+ auto substTy = partialSubstTy.subst (outerSubs );
1363
1360
1364
1361
auto partialSubstRef =
1365
1362
abstractRef.subst (archetype->getInterfaceType (), *subs);
1366
1363
auto substRef =
1367
- partialSubstRef.subst (partialSubstTy, opaqueRoot-> getSubstitutions () );
1364
+ partialSubstRef.subst (partialSubstTy, outerSubs );
1368
1365
1369
1366
// If the type still contains opaque types, recur.
1370
1367
if (substTy->hasOpaqueArchetype ()) {
1371
- SeenDecl seenKey (opaqueRoot-> getDecl (), opaqueRoot-> getSubstitutions () );
1368
+ SeenDecl seenKey (decl, outerSubs );
1372
1369
1373
1370
if (auto *alreadySeen = this ->seenDecls ) {
1374
1371
// Detect substitution loops. If we find one, just bounce the original
0 commit comments