@@ -3502,7 +3502,8 @@ ReplaceOpaqueTypesWithUnderlyingTypes::shouldPerformSubstitution(
3502
3502
3503
3503
static Type substOpaqueTypesWithUnderlyingTypesRec (
3504
3504
Type ty, const DeclContext *inContext, ResilienceExpansion contextExpansion,
3505
- bool isWholeModuleContext, SmallPtrSetImpl<OpaqueTypeDecl *> &decls) {
3505
+ bool isWholeModuleContext,
3506
+ llvm::DenseSet<ReplaceOpaqueTypesWithUnderlyingTypes::SeenDecl> &decls) {
3506
3507
ReplaceOpaqueTypesWithUnderlyingTypes replacer (inContext, contextExpansion,
3507
3508
isWholeModuleContext, decls);
3508
3509
return ty.subst (replacer, replacer, SubstFlags::SubstituteOpaqueArchetypes);
@@ -3566,7 +3567,7 @@ static bool canSubstituteTypeInto(Type ty, const DeclContext *dc,
3566
3567
3567
3568
ReplaceOpaqueTypesWithUnderlyingTypes::ReplaceOpaqueTypesWithUnderlyingTypes (
3568
3569
const DeclContext *inContext, ResilienceExpansion contextExpansion,
3569
- bool isWholeModuleContext, llvm::SmallPtrSetImpl<OpaqueTypeDecl * > &seen)
3570
+ bool isWholeModuleContext, llvm::DenseSet<SeenDecl > &seen)
3570
3571
: contextExpansion(contextExpansion),
3571
3572
inContextAndIsWholeModule(inContext, isWholeModuleContext),
3572
3573
seenDecls(&seen) {}
@@ -3618,24 +3619,25 @@ operator()(SubstitutableType *maybeOpaqueType) const {
3618
3619
3619
3620
// If the type changed, but still contains opaque types, recur.
3620
3621
if (!substTy->isEqual (maybeOpaqueType) && substTy->hasOpaqueArchetype ()) {
3622
+ SeenDecl seenKey (opaqueRoot->getDecl (), opaqueRoot->getSubstitutions ());
3621
3623
if (auto *alreadySeen = this ->seenDecls ) {
3622
3624
// Detect substitution loops. If we find one, just bounce the original
3623
3625
// type back to the caller. This substitution will fail at runtime
3624
3626
// instead.
3625
- if (!alreadySeen->insert (opaqueRoot-> getDecl () ).second ) {
3627
+ if (!alreadySeen->insert (seenKey ).second ) {
3626
3628
return maybeOpaqueType;
3627
3629
}
3628
3630
3629
3631
auto res = ::substOpaqueTypesWithUnderlyingTypesRec (
3630
3632
substTy, inContext, contextExpansion, isContextWholeModule,
3631
3633
*alreadySeen);
3632
- alreadySeen->erase (opaqueRoot-> getDecl () );
3634
+ alreadySeen->erase (seenKey );
3633
3635
return res;
3634
3636
} else {
3635
3637
// We're the top of the stack for the recursion check. Allocate a set of
3636
3638
// 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 );
3639
3641
return ::substOpaqueTypesWithUnderlyingTypesRec (
3640
3642
substTy, inContext, contextExpansion, isContextWholeModule,
3641
3643
seenDecls);
@@ -3648,7 +3650,7 @@ operator()(SubstitutableType *maybeOpaqueType) const {
3648
3650
static ProtocolConformanceRef substOpaqueTypesWithUnderlyingTypesRec (
3649
3651
ProtocolConformanceRef ref, Type origType, const DeclContext *inContext,
3650
3652
ResilienceExpansion contextExpansion, bool isWholeModuleContext,
3651
- SmallPtrSetImpl<OpaqueTypeDecl * > &decls) {
3653
+ llvm::DenseSet<ReplaceOpaqueTypesWithUnderlyingTypes::SeenDecl > &decls) {
3652
3654
ReplaceOpaqueTypesWithUnderlyingTypes replacer (inContext, contextExpansion,
3653
3655
isWholeModuleContext, decls);
3654
3656
return ref.subst (origType, replacer, replacer,
@@ -3732,24 +3734,26 @@ operator()(CanType maybeOpaqueType, Type replacementType,
3732
3734
3733
3735
// If the type still contains opaque types, recur.
3734
3736
if (substTy->hasOpaqueArchetype ()) {
3737
+ SeenDecl seenKey (opaqueRoot->getDecl (), opaqueRoot->getSubstitutions ());
3738
+
3735
3739
if (auto *alreadySeen = this ->seenDecls ) {
3736
3740
// Detect substitution loops. If we find one, just bounce the original
3737
3741
// type back to the caller. This substitution will fail at runtime
3738
3742
// instead.
3739
- if (!alreadySeen->insert (opaqueRoot-> getDecl () ).second ) {
3743
+ if (!alreadySeen->insert (seenKey ).second ) {
3740
3744
return abstractRef;
3741
3745
}
3742
3746
3743
3747
auto res = ::substOpaqueTypesWithUnderlyingTypesRec (
3744
3748
substRef, substTy, inContext, contextExpansion, isContextWholeModule,
3745
3749
*alreadySeen);
3746
- alreadySeen->erase (opaqueRoot-> getDecl () );
3750
+ alreadySeen->erase (seenKey );
3747
3751
return res;
3748
3752
} else {
3749
3753
// We're the top of the stack for the recursion check. Allocate a set of
3750
3754
// 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 );
3753
3757
return ::substOpaqueTypesWithUnderlyingTypesRec (
3754
3758
substRef, substTy, inContext, contextExpansion, isContextWholeModule,
3755
3759
seenDecls);
0 commit comments