@@ -489,6 +489,8 @@ class TypeSubstituter : public TypeTransform<TypeSubstituter> {
489489 : level(level), IFS(IFS) {}
490490
491491 std::optional<Type> transform (TypeBase *type, TypePosition position);
492+
493+ SubstitutionMap transformSubstitutionMap (SubstitutionMap subs);
492494};
493495
494496}
@@ -624,6 +626,11 @@ TypeSubstituter::transform(TypeBase *type, TypePosition position) {
624626 level);
625627}
626628
629+ SubstitutionMap TypeSubstituter::transformSubstitutionMap (SubstitutionMap subs) {
630+ // FIXME: Take level into account? Move level down into IFS?
631+ return subs.subst (IFS);
632+ }
633+
627634Type Type::subst (SubstitutionMap substitutions,
628635 SubstOptions options) const {
629636 InFlightSubstitutionViaSubMap IFS (substitutions, options);
@@ -1038,18 +1045,6 @@ Type TypeBase::adjustSuperclassMemberDeclType(const ValueDecl *baseDecl,
10381045// Replacing opaque result archetypes with their underlying types
10391046// ===----------------------------------------------------------------------===//
10401047
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-
10531048OpaqueSubstitutionKind
10541049ReplaceOpaqueTypesWithUnderlyingTypes::shouldPerformSubstitution (
10551050 OpaqueTypeDecl *opaque) const {
@@ -1187,19 +1182,20 @@ ReplaceOpaqueTypesWithUnderlyingTypes::ReplaceOpaqueTypesWithUnderlyingTypes(
11871182
11881183Type ReplaceOpaqueTypesWithUnderlyingTypes::
11891184operator ()(SubstitutableType *maybeOpaqueType) const {
1190- auto archetypeAndRoot = getArchetypeAndRootOpaqueArchetype (maybeOpaqueType);
1191- if (!archetypeAndRoot )
1185+ auto *archetype = dyn_cast<OpaqueTypeArchetypeType> (maybeOpaqueType);
1186+ if (!archetype )
11921187 return maybeOpaqueType;
11931188
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 ();
11961192
1197- auto substitutionKind = shouldPerformSubstitution (opaqueRoot-> getDecl () );
1193+ auto substitutionKind = shouldPerformSubstitution (decl );
11981194 if (substitutionKind == OpaqueSubstitutionKind::DontSubstitute) {
11991195 return maybeOpaqueType;
12001196 }
12011197
1202- auto subs = opaqueRoot-> getDecl () ->getUniqueUnderlyingTypeSubstitutions ();
1198+ auto subs = decl ->getUniqueUnderlyingTypeSubstitutions ();
12031199 // If the body of the opaque decl providing decl has not been type checked we
12041200 // don't have a underlying substitution.
12051201 if (!subs.has_value ())
@@ -1231,11 +1227,11 @@ operator()(SubstitutableType *maybeOpaqueType) const {
12311227 // for its type arguments. We perform this substitution after checking for
12321228 // visibility, since we do not want the result of the visibility check to
12331229 // depend on the substitutions previously applied.
1234- auto substTy = partialSubstTy.subst (opaqueRoot-> getSubstitutions () );
1230+ auto substTy = partialSubstTy.subst (outerSubs );
12351231
12361232 // If the type changed, but still contains opaque types, recur.
12371233 if (!substTy->isEqual (maybeOpaqueType) && substTy->hasOpaqueArchetype ()) {
1238- SeenDecl seenKey (opaqueRoot-> getDecl (), opaqueRoot-> getSubstitutions () );
1234+ SeenDecl seenKey (decl, outerSubs );
12391235 if (auto *alreadySeen = this ->seenDecls ) {
12401236 // Detect substitution loops. If we find one, just bounce the original
12411237 // type back to the caller. This substitution will fail at runtime
@@ -1305,8 +1301,8 @@ operator()(CanType maybeOpaqueType, Type replacementType,
13051301 ProtocolDecl *protocol) const {
13061302 auto abstractRef = ProtocolConformanceRef (protocol);
13071303
1308- auto archetypeAndRoot = getArchetypeAndRootOpaqueArchetype (maybeOpaqueType);
1309- if (!archetypeAndRoot ) {
1304+ auto archetype = dyn_cast<OpaqueTypeArchetypeType> (maybeOpaqueType);
1305+ if (!archetype ) {
13101306 if (maybeOpaqueType->isTypeParameter () ||
13111307 maybeOpaqueType->is <ArchetypeType>())
13121308 return abstractRef;
@@ -1320,15 +1316,16 @@ operator()(CanType maybeOpaqueType, Type replacementType,
13201316 llvm_unreachable (" origType should have been an opaque type or type parameter" );
13211317 }
13221318
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 ();
13251322
1326- auto substitutionKind = shouldPerformSubstitution (opaqueRoot-> getDecl () );
1323+ auto substitutionKind = shouldPerformSubstitution (decl );
13271324 if (substitutionKind == OpaqueSubstitutionKind::DontSubstitute) {
13281325 return abstractRef;
13291326 }
13301327
1331- auto subs = opaqueRoot-> getDecl () ->getUniqueUnderlyingTypeSubstitutions ();
1328+ auto subs = decl ->getUniqueUnderlyingTypeSubstitutions ();
13321329 // If the body of the opaque decl providing decl has not been type checked we
13331330 // don't have a underlying substitution.
13341331 if (!subs.has_value ())
@@ -1359,16 +1356,16 @@ operator()(CanType maybeOpaqueType, Type replacementType,
13591356 // for its type arguments. We perform this substitution after checking for
13601357 // visibility, since we do not want the result of the visibility check to
13611358 // depend on the substitutions previously applied.
1362- auto substTy = partialSubstTy.subst (opaqueRoot-> getSubstitutions () );
1359+ auto substTy = partialSubstTy.subst (outerSubs );
13631360
13641361 auto partialSubstRef =
13651362 abstractRef.subst (archetype->getInterfaceType (), *subs);
13661363 auto substRef =
1367- partialSubstRef.subst (partialSubstTy, opaqueRoot-> getSubstitutions () );
1364+ partialSubstRef.subst (partialSubstTy, outerSubs );
13681365
13691366 // If the type still contains opaque types, recur.
13701367 if (substTy->hasOpaqueArchetype ()) {
1371- SeenDecl seenKey (opaqueRoot-> getDecl (), opaqueRoot-> getSubstitutions () );
1368+ SeenDecl seenKey (decl, outerSubs );
13721369
13731370 if (auto *alreadySeen = this ->seenDecls ) {
13741371 // Detect substitution loops. If we find one, just bounce the original
0 commit comments