@@ -3449,7 +3449,8 @@ ReplaceOpaqueTypesWithUnderlyingTypes::shouldPerformSubstitution(
3449
3449
3450
3450
static Type substOpaqueTypesWithUnderlyingTypesRec (
3451
3451
Type ty, const DeclContext *inContext, ResilienceExpansion contextExpansion,
3452
- bool isWholeModuleContext, SmallPtrSetImpl<OpaqueTypeDecl *> &decls) {
3452
+ bool isWholeModuleContext,
3453
+ llvm::DenseSet<ReplaceOpaqueTypesWithUnderlyingTypes::SeenDecl> &decls) {
3453
3454
ReplaceOpaqueTypesWithUnderlyingTypes replacer (inContext, contextExpansion,
3454
3455
isWholeModuleContext, decls);
3455
3456
return ty.subst (replacer, replacer, SubstFlags::SubstituteOpaqueArchetypes);
@@ -3513,7 +3514,7 @@ static bool canSubstituteTypeInto(Type ty, const DeclContext *dc,
3513
3514
3514
3515
ReplaceOpaqueTypesWithUnderlyingTypes::ReplaceOpaqueTypesWithUnderlyingTypes (
3515
3516
const DeclContext *inContext, ResilienceExpansion contextExpansion,
3516
- bool isWholeModuleContext, llvm::SmallPtrSetImpl<OpaqueTypeDecl * > &seen)
3517
+ bool isWholeModuleContext, llvm::DenseSet<SeenDecl > &seen)
3517
3518
: contextExpansion(contextExpansion),
3518
3519
inContextAndIsWholeModule(inContext, isWholeModuleContext),
3519
3520
seenDecls(&seen) {}
@@ -3565,24 +3566,25 @@ operator()(SubstitutableType *maybeOpaqueType) const {
3565
3566
3566
3567
// If the type changed, but still contains opaque types, recur.
3567
3568
if (!substTy->isEqual (maybeOpaqueType) && substTy->hasOpaqueArchetype ()) {
3569
+ SeenDecl seenKey (opaqueRoot->getDecl (), opaqueRoot->getSubstitutions ());
3568
3570
if (auto *alreadySeen = this ->seenDecls ) {
3569
3571
// Detect substitution loops. If we find one, just bounce the original
3570
3572
// type back to the caller. This substitution will fail at runtime
3571
3573
// instead.
3572
- if (!alreadySeen->insert (opaqueRoot-> getDecl () ).second ) {
3574
+ if (!alreadySeen->insert (seenKey ).second ) {
3573
3575
return maybeOpaqueType;
3574
3576
}
3575
3577
3576
3578
auto res = ::substOpaqueTypesWithUnderlyingTypesRec (
3577
3579
substTy, inContext, contextExpansion, isContextWholeModule,
3578
3580
*alreadySeen);
3579
- alreadySeen->erase (opaqueRoot-> getDecl () );
3581
+ alreadySeen->erase (seenKey );
3580
3582
return res;
3581
3583
} else {
3582
3584
// We're the top of the stack for the recursion check. Allocate a set of
3583
3585
// 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 );
3586
3588
return ::substOpaqueTypesWithUnderlyingTypesRec (
3587
3589
substTy, inContext, contextExpansion, isContextWholeModule,
3588
3590
seenDecls);
@@ -3595,7 +3597,7 @@ operator()(SubstitutableType *maybeOpaqueType) const {
3595
3597
static ProtocolConformanceRef substOpaqueTypesWithUnderlyingTypesRec (
3596
3598
ProtocolConformanceRef ref, Type origType, const DeclContext *inContext,
3597
3599
ResilienceExpansion contextExpansion, bool isWholeModuleContext,
3598
- SmallPtrSetImpl<OpaqueTypeDecl * > &decls) {
3600
+ llvm::DenseSet<ReplaceOpaqueTypesWithUnderlyingTypes::SeenDecl > &decls) {
3599
3601
ReplaceOpaqueTypesWithUnderlyingTypes replacer (inContext, contextExpansion,
3600
3602
isWholeModuleContext, decls);
3601
3603
return ref.subst (origType, replacer, replacer,
@@ -3679,24 +3681,26 @@ operator()(CanType maybeOpaqueType, Type replacementType,
3679
3681
3680
3682
// If the type still contains opaque types, recur.
3681
3683
if (substTy->hasOpaqueArchetype ()) {
3684
+ SeenDecl seenKey (opaqueRoot->getDecl (), opaqueRoot->getSubstitutions ());
3685
+
3682
3686
if (auto *alreadySeen = this ->seenDecls ) {
3683
3687
// Detect substitution loops. If we find one, just bounce the original
3684
3688
// type back to the caller. This substitution will fail at runtime
3685
3689
// instead.
3686
- if (!alreadySeen->insert (opaqueRoot-> getDecl () ).second ) {
3690
+ if (!alreadySeen->insert (seenKey ).second ) {
3687
3691
return abstractRef;
3688
3692
}
3689
3693
3690
3694
auto res = ::substOpaqueTypesWithUnderlyingTypesRec (
3691
3695
substRef, substTy, inContext, contextExpansion, isContextWholeModule,
3692
3696
*alreadySeen);
3693
- alreadySeen->erase (opaqueRoot-> getDecl () );
3697
+ alreadySeen->erase (seenKey );
3694
3698
return res;
3695
3699
} else {
3696
3700
// We're the top of the stack for the recursion check. Allocate a set of
3697
3701
// 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 );
3700
3704
return ::substOpaqueTypesWithUnderlyingTypesRec (
3701
3705
substRef, substTy, inContext, contextExpansion, isContextWholeModule,
3702
3706
seenDecls);
0 commit comments