Skip to content

Commit 3512f6a

Browse files
committed
Fix name lookup in nested protocol inheritance clauses
1 parent a843d69 commit 3512f6a

File tree

2 files changed

+95
-28
lines changed

2 files changed

+95
-28
lines changed

lib/AST/NameLookup.cpp

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,7 +1087,8 @@ static DirectlyReferencedTypeDecls
10871087
directReferencesForTypeRepr(Evaluator &evaluator, ASTContext &ctx,
10881088
TypeRepr *typeRepr, DeclContext *dc,
10891089
bool allowUsableFromInline,
1090-
bool rhsOfSelfRequirement);
1090+
bool rhsOfSelfRequirement,
1091+
bool allowProtocolMembers);
10911092

10921093
/// Retrieve the set of type declarations that are directly referenced from
10931094
/// the given type.
@@ -1148,7 +1149,8 @@ SelfBounds SelfBoundsFromWhereClauseRequest::evaluate(
11481149
rhsDecls = directReferencesForTypeRepr(evaluator, ctx, typeRepr,
11491150
const_cast<DeclContext *>(dc),
11501151
/*allowUsableFromInline=*/false,
1151-
/*rhsOfSelfRequirement=*/true);
1152+
/*rhsOfSelfRequirement=*/true,
1153+
/*allowProtocolMembers=*/true);
11521154
}
11531155

11541156
SmallVector<ModuleDecl *, 2> modulesFound;
@@ -1212,7 +1214,8 @@ TypeDeclsFromWhereClauseRequest::evaluate(Evaluator &evaluator,
12121214
auto resolve = [&](TypeRepr *typeRepr) {
12131215
auto decls = directReferencesForTypeRepr(evaluator, ctx, typeRepr, ext,
12141216
/*allowUsableFromInline=*/false,
1215-
/*rhsOfSelfRequirement=*/false);
1217+
/*rhsOfSelfRequirement=*/false,
1218+
/*allowProtocolMembers=*/true);
12161219
result.first.insert(result.first.end(),
12171220
decls.first.begin(),
12181221
decls.first.end());
@@ -2843,10 +2846,11 @@ directReferencesForUnqualifiedTypeLookup(DeclNameRef name,
28432846
SourceLoc loc, DeclContext *dc,
28442847
LookupOuterResults lookupOuter,
28452848
bool allowUsableFromInline,
2846-
bool rhsOfSelfRequirement) {
2847-
UnqualifiedLookupOptions options =
2848-
UnqualifiedLookupFlags::TypeLookup |
2849-
UnqualifiedLookupFlags::AllowProtocolMembers;
2849+
bool rhsOfSelfRequirement,
2850+
bool allowProtocolMembers) {
2851+
UnqualifiedLookupOptions options = UnqualifiedLookupFlags::TypeLookup;
2852+
if (allowProtocolMembers)
2853+
options |= UnqualifiedLookupFlags::AllowProtocolMembers;
28502854
if (lookupOuter == LookupOuterResults::Included)
28512855
options |= UnqualifiedLookupFlags::IncludeOuterResults;
28522856

@@ -2960,11 +2964,12 @@ static DirectlyReferencedTypeDecls
29602964
directReferencesForDeclRefTypeRepr(Evaluator &evaluator, ASTContext &ctx,
29612965
DeclRefTypeRepr *repr, DeclContext *dc,
29622966
bool allowUsableFromInline,
2963-
bool rhsOfSelfRequirement) {
2967+
bool rhsOfSelfRequirement,
2968+
bool allowProtocolMembers) {
29642969
if (auto *qualIdentTR = dyn_cast<QualifiedIdentTypeRepr>(repr)) {
29652970
auto result = directReferencesForTypeRepr(
29662971
evaluator, ctx, qualIdentTR->getBase(), dc,
2967-
allowUsableFromInline, rhsOfSelfRequirement);
2972+
allowUsableFromInline, rhsOfSelfRequirement, allowProtocolMembers);
29682973

29692974
// For a qualified identifier, perform qualified name lookup.
29702975
result.first = directReferencesForQualifiedTypeLookup(
@@ -2977,14 +2982,15 @@ directReferencesForDeclRefTypeRepr(Evaluator &evaluator, ASTContext &ctx,
29772982
// For an unqualified identifier, perform unqualified name lookup.
29782983
return directReferencesForUnqualifiedTypeLookup(
29792984
repr->getNameRef(), repr->getLoc(), dc, LookupOuterResults::Excluded,
2980-
allowUsableFromInline, rhsOfSelfRequirement);
2985+
allowUsableFromInline, rhsOfSelfRequirement, allowProtocolMembers);
29812986
}
29822987

29832988
static DirectlyReferencedTypeDecls
29842989
directReferencesForTypeRepr(Evaluator &evaluator,
29852990
ASTContext &ctx, TypeRepr *typeRepr,
29862991
DeclContext *dc, bool allowUsableFromInline,
2987-
bool rhsOfSelfRequirement) {
2992+
bool rhsOfSelfRequirement,
2993+
bool allowProtocolMembers) {
29882994
DirectlyReferencedTypeDecls result;
29892995

29902996
switch (typeRepr->getKind()) {
@@ -2997,7 +3003,8 @@ directReferencesForTypeRepr(Evaluator &evaluator,
29973003
return directReferencesForTypeRepr(evaluator, ctx,
29983004
attributed->getTypeRepr(), dc,
29993005
allowUsableFromInline,
3000-
rhsOfSelfRequirement);
3006+
rhsOfSelfRequirement,
3007+
allowProtocolMembers);
30013008
}
30023009

30033010
case TypeReprKind::Composition: {
@@ -3006,7 +3013,8 @@ directReferencesForTypeRepr(Evaluator &evaluator,
30063013
auto componentResult =
30073014
directReferencesForTypeRepr(evaluator, ctx, component, dc,
30083015
allowUsableFromInline,
3009-
rhsOfSelfRequirement);
3016+
rhsOfSelfRequirement,
3017+
allowProtocolMembers);
30103018
result.first.insert(result.first.end(),
30113019
componentResult.first.begin(),
30123020
componentResult.first.end());
@@ -3022,7 +3030,8 @@ directReferencesForTypeRepr(Evaluator &evaluator,
30223030
return directReferencesForDeclRefTypeRepr(evaluator, ctx,
30233031
cast<DeclRefTypeRepr>(typeRepr),
30243032
dc, allowUsableFromInline,
3025-
rhsOfSelfRequirement);
3033+
rhsOfSelfRequirement,
3034+
allowProtocolMembers);
30263035

30273036
case TypeReprKind::Dictionary:
30283037
result.first.push_back(ctx.getDictionaryDecl());
@@ -3034,7 +3043,8 @@ directReferencesForTypeRepr(Evaluator &evaluator,
30343043
result = directReferencesForTypeRepr(evaluator, ctx,
30353044
tupleRepr->getElementType(0), dc,
30363045
allowUsableFromInline,
3037-
rhsOfSelfRequirement);
3046+
rhsOfSelfRequirement,
3047+
allowProtocolMembers);
30383048
} else {
30393049
result.first.push_back(ctx.getBuiltinTupleDecl());
30403050
}
@@ -3046,23 +3056,26 @@ directReferencesForTypeRepr(Evaluator &evaluator,
30463056
return directReferencesForTypeRepr(evaluator, ctx,
30473057
packExpansionRepr->getElementType(), dc,
30483058
allowUsableFromInline,
3049-
rhsOfSelfRequirement);
3059+
rhsOfSelfRequirement,
3060+
allowProtocolMembers);
30503061
}
30513062

30523063
case TypeReprKind::PackExpansion: {
30533064
auto packExpansionRepr = cast<PackExpansionTypeRepr>(typeRepr);
30543065
return directReferencesForTypeRepr(evaluator, ctx,
30553066
packExpansionRepr->getPatternType(), dc,
30563067
allowUsableFromInline,
3057-
rhsOfSelfRequirement);
3068+
rhsOfSelfRequirement,
3069+
allowProtocolMembers);
30583070
}
30593071

30603072
case TypeReprKind::PackElement: {
30613073
auto packReferenceRepr = cast<PackElementTypeRepr>(typeRepr);
30623074
return directReferencesForTypeRepr(evaluator, ctx,
30633075
packReferenceRepr->getPackType(), dc,
30643076
allowUsableFromInline,
3065-
rhsOfSelfRequirement);
3077+
rhsOfSelfRequirement,
3078+
allowProtocolMembers);
30663079
}
30673080

30683081
case TypeReprKind::Inverse: {
@@ -3072,7 +3085,8 @@ directReferencesForTypeRepr(Evaluator &evaluator,
30723085
auto innerResult = directReferencesForTypeRepr(evaluator, ctx,
30733086
inverseRepr->getConstraint(), dc,
30743087
allowUsableFromInline,
3075-
rhsOfSelfRequirement);
3088+
rhsOfSelfRequirement,
3089+
allowProtocolMembers);
30763090
if (innerResult.first.size() == 1) {
30773091
if (auto *proto = dyn_cast<ProtocolDecl>(innerResult.first[0])) {
30783092
if (auto ip = proto->getInvertibleProtocolKind()) {
@@ -3182,10 +3196,16 @@ DirectlyReferencedTypeDecls InheritedDeclsReferencedRequest::evaluate(
31823196
else
31833197
dc = (DeclContext *)decl.get<const ExtensionDecl *>();
31843198

3199+
// If looking at a protocol's inheritance list,
3200+
// do not look at protocol members to avoid circularity.
3201+
// Protocols cannot inherit from any protocol members anyway.
3202+
bool allowProtocolMembers = (dc->getSelfProtocolDecl() == nullptr);
3203+
31853204
return directReferencesForTypeRepr(evaluator, dc->getASTContext(), typeRepr,
31863205
const_cast<DeclContext *>(dc),
31873206
/*allowUsableFromInline=*/false,
3188-
/*rhsOfSelfRequirement=*/false);
3207+
/*rhsOfSelfRequirement=*/false,
3208+
allowProtocolMembers);
31893209
}
31903210

31913211
// Fall back to semantic types.
@@ -3206,7 +3226,8 @@ DirectlyReferencedTypeDecls UnderlyingTypeDeclsReferencedRequest::evaluate(
32063226
return directReferencesForTypeRepr(evaluator, typealias->getASTContext(),
32073227
typeRepr, typealias,
32083228
/*allowUsableFromInline=*/false,
3209-
/*rhsOfSelfRequirement=*/false);
3229+
/*rhsOfSelfRequirement=*/false,
3230+
/*allowProtocolMembers=*/true);
32103231
}
32113232

32123233
// Fall back to semantic types.
@@ -3373,7 +3394,8 @@ ExtendedNominalRequest::evaluate(Evaluator &evaluator,
33733394
DirectlyReferencedTypeDecls referenced =
33743395
directReferencesForTypeRepr(evaluator, ctx, typeRepr, ext->getParent(),
33753396
ext->isInSpecializeExtensionContext(),
3376-
/*rhsOfSelfRequirement=*/false);
3397+
/*rhsOfSelfRequirement=*/false,
3398+
/*allowProtocolMembers=*/true);
33773399

33783400
// Resolve those type declarations to nominal type declarations.
33793401
SmallVector<ModuleDecl *, 2> modulesFound;
@@ -3423,7 +3445,8 @@ bool TypeRepr::isProtocolOrProtocolComposition(DeclContext *dc) {
34233445
auto &ctx = dc->getASTContext();
34243446
auto references = directReferencesForTypeRepr(ctx.evaluator, ctx, this, dc,
34253447
/*allowUsableFromInline=*/false,
3426-
/*rhsOfSelfRequirement=*/false);
3448+
/*rhsOfSelfRequirement=*/false,
3449+
/*allowProtocolMembers=*/true);
34273450
return declsAreProtocols(references.first);
34283451
}
34293452

@@ -3458,7 +3481,8 @@ createTupleExtensionGenericParams(ASTContext &ctx,
34583481
extendedTypeRepr,
34593482
ext->getParent(),
34603483
/*allowUsableFromInline=*/false,
3461-
/*rhsOfSelfRequirement=*/false);
3484+
/*rhsOfSelfRequirement=*/false,
3485+
/*allowProtocolMembers=*/true);
34623486
assert(referenced.second.empty() && "Implement me");
34633487
if (referenced.first.size() != 1 || !isa<TypeAliasDecl>(referenced.first[0]))
34643488
return nullptr;
@@ -3733,7 +3757,8 @@ CustomAttrNominalRequest::evaluate(Evaluator &evaluator,
37333757
decls = directReferencesForTypeRepr(
37343758
evaluator, ctx, typeRepr, dc,
37353759
/*allowUsableFromInline=*/false,
3736-
/*rhsOfSelfRequirement=*/false);
3760+
/*rhsOfSelfRequirement=*/false,
3761+
/*allowProtocolMembers=*/true);
37373762
} else if (Type type = attr->getType()) {
37383763
decls = directReferencesForType(type);
37393764
}
@@ -3764,7 +3789,8 @@ CustomAttrNominalRequest::evaluate(Evaluator &evaluator,
37643789
decls = directReferencesForUnqualifiedTypeLookup(
37653790
name, loc, dc, LookupOuterResults::Included,
37663791
/*allowUsableFromInline=*/false,
3767-
/*rhsOfSelfRequirement=*/false);
3792+
/*rhsOfSelfRequirement=*/false,
3793+
/*allowProtocolMembers*/true);
37683794
nominals = resolveTypeDeclsToNominal(evaluator, ctx, decls.first,
37693795
ResolveToNominalOptions(),
37703796
modulesFound, anyObject);
@@ -4002,7 +4028,8 @@ ProtocolDecl *ImplementsAttrProtocolRequest::evaluate(
40024028
DirectlyReferencedTypeDecls referenced =
40034029
directReferencesForTypeRepr(evaluator, ctx, typeRepr, dc,
40044030
/*allowUsableFromInline=*/false,
4005-
/*rhsOfSelfRequirement=*/false);
4031+
/*rhsOfSelfRequirement=*/false,
4032+
/*allowProtocolMembers=*/true);
40064033

40074034
// Resolve those type declarations to nominal type declarations.
40084035
SmallVector<ModuleDecl *, 2> modulesFound;

test/decl/nested/protocol.swift

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,46 @@ class OuterClass {
4444
protocol InnerProtocol : OuterClass { }
4545
}
4646

47+
// Name lookup circularity tests.
48+
49+
protocol SomeBaseProtocol {}
50+
51+
struct ConformanceOnDecl: ConformanceOnDecl.P {
52+
protocol P: SomeBaseProtocol {}
53+
}
54+
struct ConformanceOnDecl_2: ConformanceOnDecl_2.P {
55+
protocol P where Self: SomeBaseProtocol {}
56+
}
57+
struct ConformanceOnDecl_3: Self.P {
58+
protocol P: SomeBaseProtocol {}
59+
}
60+
struct ConformanceOnDecl_4: ConformanceOnDecl_4.Q {
61+
protocol P: SomeBaseProtocol {}
62+
protocol Q: P {}
63+
}
64+
65+
66+
struct ConformanceInExtension {
67+
protocol P: SomeBaseProtocol {}
68+
}
69+
extension ConformanceInExtension: ConformanceInExtension.P {}
70+
71+
struct ConformanceInExtension_2 {
72+
protocol P where Self: SomeBaseProtocol {}
73+
}
74+
extension ConformanceInExtension_2: ConformanceInExtension_2.P {}
75+
76+
struct ConformanceInExtension_3 {
77+
protocol P: SomeBaseProtocol {}
78+
}
79+
extension ConformanceInExtension_3: Self.P {}
80+
81+
struct ConformanceInExtension_4 {
82+
protocol P: SomeBaseProtocol {}
83+
protocol Q: P {}
84+
}
85+
extension ConformanceInExtension_4: ConformanceInExtension_4.Q {}
86+
4787
// Protocols can be nested in actors.
4888

4989
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
@@ -315,4 +355,4 @@ struct Outer {
315355
typealias B = Int
316356
}
317357
}
318-
}
358+
}

0 commit comments

Comments
 (0)