@@ -3449,7 +3449,8 @@ ReplaceOpaqueTypesWithUnderlyingTypes::shouldPerformSubstitution(
34493449
34503450static Type substOpaqueTypesWithUnderlyingTypesRec (
34513451 Type ty, const DeclContext *inContext, ResilienceExpansion contextExpansion,
3452- bool isWholeModuleContext, SmallPtrSetImpl<OpaqueTypeDecl *> &decls) {
3452+ bool isWholeModuleContext,
3453+ llvm::DenseSet<ReplaceOpaqueTypesWithUnderlyingTypes::SeenDecl> &decls) {
34533454 ReplaceOpaqueTypesWithUnderlyingTypes replacer (inContext, contextExpansion,
34543455 isWholeModuleContext, decls);
34553456 return ty.subst (replacer, replacer, SubstFlags::SubstituteOpaqueArchetypes);
@@ -3513,7 +3514,7 @@ static bool canSubstituteTypeInto(Type ty, const DeclContext *dc,
35133514
35143515ReplaceOpaqueTypesWithUnderlyingTypes::ReplaceOpaqueTypesWithUnderlyingTypes (
35153516 const DeclContext *inContext, ResilienceExpansion contextExpansion,
3516- bool isWholeModuleContext, llvm::SmallPtrSetImpl<OpaqueTypeDecl * > &seen)
3517+ bool isWholeModuleContext, llvm::DenseSet<SeenDecl > &seen)
35173518 : contextExpansion(contextExpansion),
35183519 inContextAndIsWholeModule(inContext, isWholeModuleContext),
35193520 seenDecls(&seen) {}
@@ -3565,24 +3566,25 @@ operator()(SubstitutableType *maybeOpaqueType) const {
35653566
35663567 // If the type changed, but still contains opaque types, recur.
35673568 if (!substTy->isEqual (maybeOpaqueType) && substTy->hasOpaqueArchetype ()) {
3569+ SeenDecl seenKey (opaqueRoot->getDecl (), opaqueRoot->getSubstitutions ());
35683570 if (auto *alreadySeen = this ->seenDecls ) {
35693571 // Detect substitution loops. If we find one, just bounce the original
35703572 // type back to the caller. This substitution will fail at runtime
35713573 // instead.
3572- if (!alreadySeen->insert (opaqueRoot-> getDecl () ).second ) {
3574+ if (!alreadySeen->insert (seenKey ).second ) {
35733575 return maybeOpaqueType;
35743576 }
35753577
35763578 auto res = ::substOpaqueTypesWithUnderlyingTypesRec (
35773579 substTy, inContext, contextExpansion, isContextWholeModule,
35783580 *alreadySeen);
3579- alreadySeen->erase (opaqueRoot-> getDecl () );
3581+ alreadySeen->erase (seenKey );
35803582 return res;
35813583 } else {
35823584 // We're the top of the stack for the recursion check. Allocate a set of
35833585 // opaque result type decls we've already seen for the rest of the check.
3584- SmallPtrSet<OpaqueTypeDecl *, 8 > seenDecls;
3585- seenDecls.insert (opaqueRoot-> getDecl () );
3586+ llvm::DenseSet<SeenDecl > seenDecls;
3587+ seenDecls.insert (seenKey );
35863588 return ::substOpaqueTypesWithUnderlyingTypesRec (
35873589 substTy, inContext, contextExpansion, isContextWholeModule,
35883590 seenDecls);
@@ -3595,7 +3597,7 @@ operator()(SubstitutableType *maybeOpaqueType) const {
35953597static ProtocolConformanceRef substOpaqueTypesWithUnderlyingTypesRec (
35963598 ProtocolConformanceRef ref, Type origType, const DeclContext *inContext,
35973599 ResilienceExpansion contextExpansion, bool isWholeModuleContext,
3598- SmallPtrSetImpl<OpaqueTypeDecl * > &decls) {
3600+ llvm::DenseSet<ReplaceOpaqueTypesWithUnderlyingTypes::SeenDecl > &decls) {
35993601 ReplaceOpaqueTypesWithUnderlyingTypes replacer (inContext, contextExpansion,
36003602 isWholeModuleContext, decls);
36013603 return ref.subst (origType, replacer, replacer,
@@ -3679,24 +3681,26 @@ operator()(CanType maybeOpaqueType, Type replacementType,
36793681
36803682 // If the type still contains opaque types, recur.
36813683 if (substTy->hasOpaqueArchetype ()) {
3684+ SeenDecl seenKey (opaqueRoot->getDecl (), opaqueRoot->getSubstitutions ());
3685+
36823686 if (auto *alreadySeen = this ->seenDecls ) {
36833687 // Detect substitution loops. If we find one, just bounce the original
36843688 // type back to the caller. This substitution will fail at runtime
36853689 // instead.
3686- if (!alreadySeen->insert (opaqueRoot-> getDecl () ).second ) {
3690+ if (!alreadySeen->insert (seenKey ).second ) {
36873691 return abstractRef;
36883692 }
36893693
36903694 auto res = ::substOpaqueTypesWithUnderlyingTypesRec (
36913695 substRef, substTy, inContext, contextExpansion, isContextWholeModule,
36923696 *alreadySeen);
3693- alreadySeen->erase (opaqueRoot-> getDecl () );
3697+ alreadySeen->erase (seenKey );
36943698 return res;
36953699 } else {
36963700 // We're the top of the stack for the recursion check. Allocate a set of
36973701 // opaque result type decls we've already seen for the rest of the check.
3698- SmallPtrSet<OpaqueTypeDecl *, 8 > seenDecls;
3699- seenDecls.insert (opaqueRoot-> getDecl () );
3702+ llvm::DenseSet<SeenDecl > seenDecls;
3703+ seenDecls.insert (seenKey );
37003704 return ::substOpaqueTypesWithUnderlyingTypesRec (
37013705 substRef, substTy, inContext, contextExpansion, isContextWholeModule,
37023706 seenDecls);
0 commit comments