@@ -3502,7 +3502,8 @@ ReplaceOpaqueTypesWithUnderlyingTypes::shouldPerformSubstitution(
35023502
35033503static Type substOpaqueTypesWithUnderlyingTypesRec (
35043504 Type ty, const DeclContext *inContext, ResilienceExpansion contextExpansion,
3505- bool isWholeModuleContext, SmallPtrSetImpl<OpaqueTypeDecl *> &decls) {
3505+ bool isWholeModuleContext,
3506+ llvm::DenseSet<ReplaceOpaqueTypesWithUnderlyingTypes::SeenDecl> &decls) {
35063507 ReplaceOpaqueTypesWithUnderlyingTypes replacer (inContext, contextExpansion,
35073508 isWholeModuleContext, decls);
35083509 return ty.subst (replacer, replacer, SubstFlags::SubstituteOpaqueArchetypes);
@@ -3566,7 +3567,7 @@ static bool canSubstituteTypeInto(Type ty, const DeclContext *dc,
35663567
35673568ReplaceOpaqueTypesWithUnderlyingTypes::ReplaceOpaqueTypesWithUnderlyingTypes (
35683569 const DeclContext *inContext, ResilienceExpansion contextExpansion,
3569- bool isWholeModuleContext, llvm::SmallPtrSetImpl<OpaqueTypeDecl * > &seen)
3570+ bool isWholeModuleContext, llvm::DenseSet<SeenDecl > &seen)
35703571 : contextExpansion(contextExpansion),
35713572 inContextAndIsWholeModule(inContext, isWholeModuleContext),
35723573 seenDecls(&seen) {}
@@ -3618,24 +3619,25 @@ operator()(SubstitutableType *maybeOpaqueType) const {
36183619
36193620 // If the type changed, but still contains opaque types, recur.
36203621 if (!substTy->isEqual (maybeOpaqueType) && substTy->hasOpaqueArchetype ()) {
3622+ SeenDecl seenKey (opaqueRoot->getDecl (), opaqueRoot->getSubstitutions ());
36213623 if (auto *alreadySeen = this ->seenDecls ) {
36223624 // Detect substitution loops. If we find one, just bounce the original
36233625 // type back to the caller. This substitution will fail at runtime
36243626 // instead.
3625- if (!alreadySeen->insert (opaqueRoot-> getDecl () ).second ) {
3627+ if (!alreadySeen->insert (seenKey ).second ) {
36263628 return maybeOpaqueType;
36273629 }
36283630
36293631 auto res = ::substOpaqueTypesWithUnderlyingTypesRec (
36303632 substTy, inContext, contextExpansion, isContextWholeModule,
36313633 *alreadySeen);
3632- alreadySeen->erase (opaqueRoot-> getDecl () );
3634+ alreadySeen->erase (seenKey );
36333635 return res;
36343636 } else {
36353637 // We're the top of the stack for the recursion check. Allocate a set of
36363638 // opaque result type decls we've already seen for the rest of the check.
3637- SmallPtrSet<OpaqueTypeDecl *, 8 > seenDecls;
3638- seenDecls.insert (opaqueRoot-> getDecl () );
3639+ llvm::DenseSet<SeenDecl > seenDecls;
3640+ seenDecls.insert (seenKey );
36393641 return ::substOpaqueTypesWithUnderlyingTypesRec (
36403642 substTy, inContext, contextExpansion, isContextWholeModule,
36413643 seenDecls);
@@ -3648,7 +3650,7 @@ operator()(SubstitutableType *maybeOpaqueType) const {
36483650static ProtocolConformanceRef substOpaqueTypesWithUnderlyingTypesRec (
36493651 ProtocolConformanceRef ref, Type origType, const DeclContext *inContext,
36503652 ResilienceExpansion contextExpansion, bool isWholeModuleContext,
3651- SmallPtrSetImpl<OpaqueTypeDecl * > &decls) {
3653+ llvm::DenseSet<ReplaceOpaqueTypesWithUnderlyingTypes::SeenDecl > &decls) {
36523654 ReplaceOpaqueTypesWithUnderlyingTypes replacer (inContext, contextExpansion,
36533655 isWholeModuleContext, decls);
36543656 return ref.subst (origType, replacer, replacer,
@@ -3732,24 +3734,26 @@ operator()(CanType maybeOpaqueType, Type replacementType,
37323734
37333735 // If the type still contains opaque types, recur.
37343736 if (substTy->hasOpaqueArchetype ()) {
3737+ SeenDecl seenKey (opaqueRoot->getDecl (), opaqueRoot->getSubstitutions ());
3738+
37353739 if (auto *alreadySeen = this ->seenDecls ) {
37363740 // Detect substitution loops. If we find one, just bounce the original
37373741 // type back to the caller. This substitution will fail at runtime
37383742 // instead.
3739- if (!alreadySeen->insert (opaqueRoot-> getDecl () ).second ) {
3743+ if (!alreadySeen->insert (seenKey ).second ) {
37403744 return abstractRef;
37413745 }
37423746
37433747 auto res = ::substOpaqueTypesWithUnderlyingTypesRec (
37443748 substRef, substTy, inContext, contextExpansion, isContextWholeModule,
37453749 *alreadySeen);
3746- alreadySeen->erase (opaqueRoot-> getDecl () );
3750+ alreadySeen->erase (seenKey );
37473751 return res;
37483752 } else {
37493753 // We're the top of the stack for the recursion check. Allocate a set of
37503754 // opaque result type decls we've already seen for the rest of the check.
3751- SmallPtrSet<OpaqueTypeDecl *, 8 > seenDecls;
3752- seenDecls.insert (opaqueRoot-> getDecl () );
3755+ llvm::DenseSet<SeenDecl > seenDecls;
3756+ seenDecls.insert (seenKey );
37533757 return ::substOpaqueTypesWithUnderlyingTypesRec (
37543758 substRef, substTy, inContext, contextExpansion, isContextWholeModule,
37553759 seenDecls);
0 commit comments