@@ -864,27 +864,35 @@ class OverrideFilteringConsumer : public VisibleDeclConsumer {
864
864
865
865
struct KeyPathDynamicMemberConsumer : public VisibleDeclConsumer {
866
866
VisibleDeclConsumer &consumer;
867
- std::function<bool (DeclBaseName)> seenBaseName;
867
+ std::function<bool (DeclBaseName)> seenStaticBaseName;
868
+ llvm::DenseSet<DeclBaseName> seen;
868
869
869
870
SubscriptDecl *currentSubscript = nullptr ;
870
871
Type currentBaseType = Type();
871
872
872
873
KeyPathDynamicMemberConsumer (VisibleDeclConsumer &consumer,
873
874
std::function<bool (DeclBaseName)> seenBaseName)
874
- : consumer(consumer), seenBaseName(std::move(seenBaseName)) {}
875
+ : consumer(consumer), seenStaticBaseName(std::move(seenBaseName)) {}
876
+
877
+ bool checkShadowed (ValueDecl *VD) {
878
+ // Dynamic lookup members are only visible if they are not shadowed by
879
+ // other members.
880
+ return !isa<SubscriptDecl>(VD) && seen.insert (VD->getBaseName ()).second &&
881
+ !seenStaticBaseName (VD->getBaseName ());
882
+ }
875
883
876
884
void foundDecl (ValueDecl *VD, DeclVisibilityKind reason,
877
885
DynamicLookupInfo dynamicLookupInfo) override {
886
+ assert (dynamicLookupInfo.getKind () !=
887
+ DynamicLookupInfo::KeyPathDynamicMember);
888
+
878
889
// Only variables and subscripts are allowed in a keypath.
879
890
if (!isa<AbstractStorageDecl>(VD))
880
891
return ;
881
892
882
- assert (dynamicLookupInfo.getKind () !=
883
- DynamicLookupInfo::KeyPathDynamicMember);
884
-
885
893
// Dynamic lookup members are only visible if they are not shadowed by
886
894
// non-dynamic members.
887
- if (isa<SubscriptDecl> (VD) || ! seenBaseName (VD-> getBaseName () ))
895
+ if (checkShadowed (VD))
888
896
consumer.foundDecl (VD, DeclVisibilityKind::DynamicLookup,
889
897
{currentSubscript, currentBaseType, reason});
890
898
}
@@ -913,7 +921,28 @@ static void lookupVisibleDynamicMemberLookupDecls(
913
921
Type baseType, KeyPathDynamicMemberConsumer &consumer,
914
922
const DeclContext *dc, LookupState LS, DeclVisibilityKind reason,
915
923
LazyResolver *typeResolver, GenericSignatureBuilder *GSB,
916
- VisitedSet &visited) {
924
+ VisitedSet &visited, llvm::DenseSet<TypeBase *> &seenDynamicLookup);
925
+
926
+ static void lookupVisibleMemberAndDynamicMemberDecls (
927
+ Type baseType, VisibleDeclConsumer &consumer,
928
+ KeyPathDynamicMemberConsumer &dynamicMemberConsumer, const DeclContext *DC,
929
+ LookupState LS, DeclVisibilityKind reason, LazyResolver *typeResolver,
930
+ GenericSignatureBuilder *GSB, VisitedSet &visited,
931
+ llvm::DenseSet<TypeBase *> &seenDynamicLookup) {
932
+ lookupVisibleMemberDeclsImpl (baseType, consumer, DC, LS, reason, typeResolver,
933
+ GSB, visited);
934
+ lookupVisibleDynamicMemberLookupDecls (baseType, dynamicMemberConsumer, DC, LS,
935
+ reason, typeResolver, GSB, visited,
936
+ seenDynamicLookup);
937
+ }
938
+
939
+ static void lookupVisibleDynamicMemberLookupDecls (
940
+ Type baseType, KeyPathDynamicMemberConsumer &consumer,
941
+ const DeclContext *dc, LookupState LS, DeclVisibilityKind reason,
942
+ LazyResolver *typeResolver, GenericSignatureBuilder *GSB,
943
+ VisitedSet &visited, llvm::DenseSet<TypeBase *> &seenDynamicLookup) {
944
+ if (!seenDynamicLookup.insert (baseType.getPointer ()).second )
945
+ return ;
917
946
918
947
if (!hasDynamicMemberLookupAttribute (baseType))
919
948
return ;
@@ -946,8 +975,9 @@ static void lookupVisibleDynamicMemberLookupDecls(
946
975
KeyPathDynamicMemberConsumer::SubscriptChange (consumer, subscript,
947
976
baseType);
948
977
949
- lookupVisibleMemberDeclsImpl (memberType, consumer, dc, LS, reason,
950
- typeResolver, GSB, visited);
978
+ lookupVisibleMemberAndDynamicMemberDecls (memberType, consumer, consumer, dc,
979
+ LS, reason, typeResolver, GSB,
980
+ visited, seenDynamicLookup);
951
981
}
952
982
}
953
983
@@ -963,15 +993,14 @@ static void lookupVisibleMemberDecls(
963
993
GenericSignatureBuilder *GSB) {
964
994
OverrideFilteringConsumer overrideConsumer (BaseTy, CurrDC, TypeResolver);
965
995
KeyPathDynamicMemberConsumer dynamicConsumer (
966
- overrideConsumer ,
996
+ Consumer ,
967
997
[&](DeclBaseName name) { return overrideConsumer.seenBaseName (name); });
968
998
969
999
VisitedSet Visited;
970
- lookupVisibleMemberDeclsImpl (BaseTy, overrideConsumer, CurrDC, LS, Reason,
971
- TypeResolver, GSB, Visited);
972
-
973
- lookupVisibleDynamicMemberLookupDecls (BaseTy, dynamicConsumer, CurrDC, LS,
974
- Reason, TypeResolver, GSB, Visited);
1000
+ llvm::DenseSet<TypeBase *> seenDynamicLookup;
1001
+ lookupVisibleMemberAndDynamicMemberDecls (
1002
+ BaseTy, overrideConsumer, dynamicConsumer, CurrDC, LS, Reason,
1003
+ TypeResolver, GSB, Visited, seenDynamicLookup);
975
1004
976
1005
// Report the declarations we found to the real consumer.
977
1006
for (const auto &DeclAndReason : overrideConsumer.DeclsToReport )
0 commit comments