Skip to content

Commit 6164ee5

Browse files
committed
Fix name lookup in nested protocol inheritance clauses
1 parent fc6011c commit 6164ee5

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());
@@ -2834,10 +2837,11 @@ directReferencesForUnqualifiedTypeLookup(DeclNameRef name,
28342837
SourceLoc loc, DeclContext *dc,
28352838
LookupOuterResults lookupOuter,
28362839
bool allowUsableFromInline,
2837-
bool rhsOfSelfRequirement) {
2838-
UnqualifiedLookupOptions options =
2839-
UnqualifiedLookupFlags::TypeLookup |
2840-
UnqualifiedLookupFlags::AllowProtocolMembers;
2840+
bool rhsOfSelfRequirement,
2841+
bool allowProtocolMembers) {
2842+
UnqualifiedLookupOptions options = UnqualifiedLookupFlags::TypeLookup;
2843+
if (allowProtocolMembers)
2844+
options |= UnqualifiedLookupFlags::AllowProtocolMembers;
28412845
if (lookupOuter == LookupOuterResults::Included)
28422846
options |= UnqualifiedLookupFlags::IncludeOuterResults;
28432847

@@ -2951,11 +2955,12 @@ static DirectlyReferencedTypeDecls
29512955
directReferencesForDeclRefTypeRepr(Evaluator &evaluator, ASTContext &ctx,
29522956
DeclRefTypeRepr *repr, DeclContext *dc,
29532957
bool allowUsableFromInline,
2954-
bool rhsOfSelfRequirement) {
2958+
bool rhsOfSelfRequirement,
2959+
bool allowProtocolMembers) {
29552960
if (auto *qualIdentTR = dyn_cast<QualifiedIdentTypeRepr>(repr)) {
29562961
auto result = directReferencesForTypeRepr(
29572962
evaluator, ctx, qualIdentTR->getBase(), dc,
2958-
allowUsableFromInline, rhsOfSelfRequirement);
2963+
allowUsableFromInline, rhsOfSelfRequirement, allowProtocolMembers);
29592964

29602965
// For a qualified identifier, perform qualified name lookup.
29612966
result.first = directReferencesForQualifiedTypeLookup(
@@ -2968,14 +2973,15 @@ directReferencesForDeclRefTypeRepr(Evaluator &evaluator, ASTContext &ctx,
29682973
// For an unqualified identifier, perform unqualified name lookup.
29692974
return directReferencesForUnqualifiedTypeLookup(
29702975
repr->getNameRef(), repr->getLoc(), dc, LookupOuterResults::Excluded,
2971-
allowUsableFromInline, rhsOfSelfRequirement);
2976+
allowUsableFromInline, rhsOfSelfRequirement, allowProtocolMembers);
29722977
}
29732978

29742979
static DirectlyReferencedTypeDecls
29752980
directReferencesForTypeRepr(Evaluator &evaluator,
29762981
ASTContext &ctx, TypeRepr *typeRepr,
29772982
DeclContext *dc, bool allowUsableFromInline,
2978-
bool rhsOfSelfRequirement) {
2983+
bool rhsOfSelfRequirement,
2984+
bool allowProtocolMembers) {
29792985
DirectlyReferencedTypeDecls result;
29802986

29812987
switch (typeRepr->getKind()) {
@@ -2988,7 +2994,8 @@ directReferencesForTypeRepr(Evaluator &evaluator,
29882994
return directReferencesForTypeRepr(evaluator, ctx,
29892995
attributed->getTypeRepr(), dc,
29902996
allowUsableFromInline,
2991-
rhsOfSelfRequirement);
2997+
rhsOfSelfRequirement,
2998+
allowProtocolMembers);
29922999
}
29933000

29943001
case TypeReprKind::Composition: {
@@ -2997,7 +3004,8 @@ directReferencesForTypeRepr(Evaluator &evaluator,
29973004
auto componentResult =
29983005
directReferencesForTypeRepr(evaluator, ctx, component, dc,
29993006
allowUsableFromInline,
3000-
rhsOfSelfRequirement);
3007+
rhsOfSelfRequirement,
3008+
allowProtocolMembers);
30013009
result.first.insert(result.first.end(),
30023010
componentResult.first.begin(),
30033011
componentResult.first.end());
@@ -3013,7 +3021,8 @@ directReferencesForTypeRepr(Evaluator &evaluator,
30133021
return directReferencesForDeclRefTypeRepr(evaluator, ctx,
30143022
cast<DeclRefTypeRepr>(typeRepr),
30153023
dc, allowUsableFromInline,
3016-
rhsOfSelfRequirement);
3024+
rhsOfSelfRequirement,
3025+
allowProtocolMembers);
30173026

30183027
case TypeReprKind::Dictionary:
30193028
result.first.push_back(ctx.getDictionaryDecl());
@@ -3025,7 +3034,8 @@ directReferencesForTypeRepr(Evaluator &evaluator,
30253034
result = directReferencesForTypeRepr(evaluator, ctx,
30263035
tupleRepr->getElementType(0), dc,
30273036
allowUsableFromInline,
3028-
rhsOfSelfRequirement);
3037+
rhsOfSelfRequirement,
3038+
allowProtocolMembers);
30293039
} else {
30303040
result.first.push_back(ctx.getBuiltinTupleDecl());
30313041
}
@@ -3037,23 +3047,26 @@ directReferencesForTypeRepr(Evaluator &evaluator,
30373047
return directReferencesForTypeRepr(evaluator, ctx,
30383048
packExpansionRepr->getElementType(), dc,
30393049
allowUsableFromInline,
3040-
rhsOfSelfRequirement);
3050+
rhsOfSelfRequirement,
3051+
allowProtocolMembers);
30413052
}
30423053

30433054
case TypeReprKind::PackExpansion: {
30443055
auto packExpansionRepr = cast<PackExpansionTypeRepr>(typeRepr);
30453056
return directReferencesForTypeRepr(evaluator, ctx,
30463057
packExpansionRepr->getPatternType(), dc,
30473058
allowUsableFromInline,
3048-
rhsOfSelfRequirement);
3059+
rhsOfSelfRequirement,
3060+
allowProtocolMembers);
30493061
}
30503062

30513063
case TypeReprKind::PackElement: {
30523064
auto packReferenceRepr = cast<PackElementTypeRepr>(typeRepr);
30533065
return directReferencesForTypeRepr(evaluator, ctx,
30543066
packReferenceRepr->getPackType(), dc,
30553067
allowUsableFromInline,
3056-
rhsOfSelfRequirement);
3068+
rhsOfSelfRequirement,
3069+
allowProtocolMembers);
30573070
}
30583071

30593072
case TypeReprKind::Inverse: {
@@ -3063,7 +3076,8 @@ directReferencesForTypeRepr(Evaluator &evaluator,
30633076
auto innerResult = directReferencesForTypeRepr(evaluator, ctx,
30643077
inverseRepr->getConstraint(), dc,
30653078
allowUsableFromInline,
3066-
rhsOfSelfRequirement);
3079+
rhsOfSelfRequirement,
3080+
allowProtocolMembers);
30673081
if (innerResult.first.size() == 1) {
30683082
if (auto *proto = dyn_cast<ProtocolDecl>(innerResult.first[0])) {
30693083
if (auto ip = proto->getInvertibleProtocolKind()) {
@@ -3173,10 +3187,16 @@ DirectlyReferencedTypeDecls InheritedDeclsReferencedRequest::evaluate(
31733187
else
31743188
dc = (DeclContext *)decl.get<const ExtensionDecl *>();
31753189

3190+
// If looking at a protocol's inheritance list,
3191+
// do not look at protocol members to avoid circularity.
3192+
// Protocols cannot inherit from any protocol members anyway.
3193+
bool allowProtocolMembers = (dc->getSelfProtocolDecl() == nullptr);
3194+
31763195
return directReferencesForTypeRepr(evaluator, dc->getASTContext(), typeRepr,
31773196
const_cast<DeclContext *>(dc),
31783197
/*allowUsableFromInline=*/false,
3179-
/*rhsOfSelfRequirement=*/false);
3198+
/*rhsOfSelfRequirement=*/false,
3199+
allowProtocolMembers);
31803200
}
31813201

31823202
// Fall back to semantic types.
@@ -3197,7 +3217,8 @@ DirectlyReferencedTypeDecls UnderlyingTypeDeclsReferencedRequest::evaluate(
31973217
return directReferencesForTypeRepr(evaluator, typealias->getASTContext(),
31983218
typeRepr, typealias,
31993219
/*allowUsableFromInline=*/false,
3200-
/*rhsOfSelfRequirement=*/false);
3220+
/*rhsOfSelfRequirement=*/false,
3221+
/*allowProtocolMembers=*/true);
32013222
}
32023223

32033224
// Fall back to semantic types.
@@ -3356,7 +3377,8 @@ ExtendedNominalRequest::evaluate(Evaluator &evaluator,
33563377
DirectlyReferencedTypeDecls referenced =
33573378
directReferencesForTypeRepr(evaluator, ctx, typeRepr, ext->getParent(),
33583379
ext->isInSpecializeExtensionContext(),
3359-
/*rhsOfSelfRequirement=*/false);
3380+
/*rhsOfSelfRequirement=*/false,
3381+
/*allowProtocolMembers=*/true);
33603382

33613383
// Resolve those type declarations to nominal type declarations.
33623384
SmallVector<ModuleDecl *, 2> modulesFound;
@@ -3406,7 +3428,8 @@ bool TypeRepr::isProtocolOrProtocolComposition(DeclContext *dc) {
34063428
auto &ctx = dc->getASTContext();
34073429
auto references = directReferencesForTypeRepr(ctx.evaluator, ctx, this, dc,
34083430
/*allowUsableFromInline=*/false,
3409-
/*rhsOfSelfRequirement=*/false);
3431+
/*rhsOfSelfRequirement=*/false,
3432+
/*allowProtocolMembers=*/true);
34103433
return declsAreProtocols(references.first);
34113434
}
34123435

@@ -3441,7 +3464,8 @@ createTupleExtensionGenericParams(ASTContext &ctx,
34413464
extendedTypeRepr,
34423465
ext->getParent(),
34433466
/*allowUsableFromInline=*/false,
3444-
/*rhsOfSelfRequirement=*/false);
3467+
/*rhsOfSelfRequirement=*/false,
3468+
/*allowProtocolMembers=*/true);
34453469
assert(referenced.second.empty() && "Implement me");
34463470
if (referenced.first.size() != 1 || !isa<TypeAliasDecl>(referenced.first[0]))
34473471
return nullptr;
@@ -3716,7 +3740,8 @@ CustomAttrNominalRequest::evaluate(Evaluator &evaluator,
37163740
decls = directReferencesForTypeRepr(
37173741
evaluator, ctx, typeRepr, dc,
37183742
/*allowUsableFromInline=*/false,
3719-
/*rhsOfSelfRequirement=*/false);
3743+
/*rhsOfSelfRequirement=*/false,
3744+
/*allowProtocolMembers=*/true);
37203745
} else if (Type type = attr->getType()) {
37213746
decls = directReferencesForType(type);
37223747
}
@@ -3747,7 +3772,8 @@ CustomAttrNominalRequest::evaluate(Evaluator &evaluator,
37473772
decls = directReferencesForUnqualifiedTypeLookup(
37483773
name, loc, dc, LookupOuterResults::Included,
37493774
/*allowUsableFromInline=*/false,
3750-
/*rhsOfSelfRequirement=*/false);
3775+
/*rhsOfSelfRequirement=*/false,
3776+
/*allowProtocolMembers*/true);
37513777
nominals = resolveTypeDeclsToNominal(evaluator, ctx, decls.first,
37523778
ResolveToNominalOptions(),
37533779
modulesFound, anyObject);
@@ -3982,7 +4008,8 @@ ProtocolDecl *ImplementsAttrProtocolRequest::evaluate(
39824008
DirectlyReferencedTypeDecls referenced =
39834009
directReferencesForTypeRepr(evaluator, ctx, typeRepr, dc,
39844010
/*allowUsableFromInline=*/false,
3985-
/*rhsOfSelfRequirement=*/false);
4011+
/*rhsOfSelfRequirement=*/false,
4012+
/*allowProtocolMembers=*/true);
39864013

39874014
// Resolve those type declarations to nominal type declarations.
39884015
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)