@@ -415,7 +415,9 @@ static void lookupDeclsFromProtocolsBeingConformedTo(
415
415
}
416
416
417
417
DeclVisibilityKind ReasonForThisProtocol;
418
- if (Reason == DeclVisibilityKind::MemberOfCurrentNominal)
418
+ if (Conformance->getKind () == ProtocolConformanceKind::Inherited)
419
+ ReasonForThisProtocol = getReasonForSuper (Reason);
420
+ else if (Reason == DeclVisibilityKind::MemberOfCurrentNominal)
419
421
ReasonForThisProtocol =
420
422
DeclVisibilityKind::MemberOfProtocolImplementedByCurrentNominal;
421
423
else
@@ -629,50 +631,61 @@ static void lookupVisibleMemberDeclsImpl(
629
631
}
630
632
}
631
633
632
- llvm::SmallPtrSet<ClassDecl *, 8 > Ancestors;
633
- do {
634
- NominalTypeDecl *CurNominal = BaseTy->getAnyNominal ();
635
- if (!CurNominal)
636
- break ;
637
-
638
- synthesizeMemberDeclsForLookup (CurNominal, CurrDC);
634
+ const auto synthesizeAndLookupTypeMembers = [&](NominalTypeDecl *NTD) {
635
+ synthesizeMemberDeclsForLookup (NTD, CurrDC);
639
636
640
637
// Look in for members of a nominal type.
641
638
lookupTypeMembers (BaseTy, BaseTy, Consumer, CurrDC, LS, Reason);
639
+ };
640
+
641
+ llvm::SmallPtrSet<ClassDecl *, 8 > Ancestors;
642
+ {
643
+ const auto NTD = BaseTy->getAnyNominal ();
644
+ if (NTD == nullptr )
645
+ return ;
646
+
647
+ synthesizeAndLookupTypeMembers (NTD);
648
+ // Look into protocols only on the current nominal to avoid repeatedly
649
+ // visiting inherited conformances.
642
650
lookupDeclsFromProtocolsBeingConformedTo (BaseTy, Consumer, LS, CurrDC,
643
651
Reason, Visited);
644
- // If we have a class type, look into its superclass.
645
- auto *CurClass = dyn_cast<ClassDecl>(CurNominal );
652
+
653
+ const auto CD = dyn_cast<ClassDecl>(NTD );
646
654
647
655
// FIXME: We check `getSuperclass()` here because we'll be using the
648
656
// superclass Type below, and in ill-formed code `hasSuperclass()` could
649
657
// be true while `getSuperclass()` returns null, because the latter
650
658
// looks for a declaration.
651
- if (CurClass && CurClass->getSuperclass ()) {
652
- // FIXME: This path is no substitute for an actual circularity check.
653
- // The real fix is to check that the superclass doesn't introduce a
654
- // circular reference before it's written into the AST.
655
- if (Ancestors.count (CurClass)) {
656
- break ;
657
- }
659
+ if (!CD || !CD->getSuperclass ())
660
+ return ;
658
661
659
- BaseTy = CurClass->getSuperclass ();
660
- Reason = getReasonForSuper (Reason);
661
-
662
- bool InheritsSuperclassInitializers =
663
- CurClass->inheritsSuperclassInitializers ();
664
- if (LS.isOnSuperclass () && !InheritsSuperclassInitializers)
665
- LS = LS.withoutInheritsSuperclassInitializers ();
666
- else if (!LS.isOnSuperclass ()) {
667
- LS = LS.withOnSuperclass ();
668
- if (InheritsSuperclassInitializers)
669
- LS = LS.withInheritsSuperclassInitializers ();
670
- }
671
- } else {
662
+ // We have a superclass; switch state and look into the inheritance chain.
663
+ Ancestors.insert (CD);
664
+
665
+ Reason = getReasonForSuper (Reason);
666
+ BaseTy = CD->getSuperclass ();
667
+
668
+ LS = LS.withOnSuperclass ();
669
+ if (CD->inheritsSuperclassInitializers ())
670
+ LS = LS.withInheritsSuperclassInitializers ();
671
+ }
672
+
673
+ // Look into the inheritance chain.
674
+ do {
675
+ const auto CurClass = BaseTy->getClassOrBoundGenericClass ();
676
+
677
+ // FIXME: This path is no substitute for an actual circularity check.
678
+ // The real fix is to check that the superclass doesn't introduce a
679
+ // circular reference before it's written into the AST.
680
+ if (!Ancestors.insert (CurClass).second )
672
681
break ;
673
- }
674
- Ancestors.insert (CurClass);
675
- } while (1 );
682
+
683
+ synthesizeAndLookupTypeMembers (CurClass);
684
+
685
+ BaseTy = CurClass->getSuperclass ();
686
+ if (!CurClass->inheritsSuperclassInitializers ())
687
+ LS = LS.withoutInheritsSuperclassInitializers ();
688
+ } while (BaseTy);
676
689
}
677
690
678
691
swift::DynamicLookupInfo::DynamicLookupInfo (
0 commit comments