Skip to content

Commit bccf135

Browse files
authored
Merge pull request swiftlang#75736 from tshortli/directly-referenced-type-lookup-refactor
2 parents 739e658 + 3c6d0bd commit bccf135

File tree

1 file changed

+92
-113
lines changed

1 file changed

+92
-113
lines changed

lib/AST/NameLookup.cpp

Lines changed: 92 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,14 +1082,36 @@ namespace {
10821082
};
10831083
}
10841084

1085+
enum class DirectlyReferencedTypeLookupFlags {
1086+
/// Include results that are `@inlinable` or `@usableFromInline`.
1087+
AllowUsableFromInline = 1 << 0,
1088+
1089+
/// Discard 'Self' requirements in protocol extension `where` clauses.
1090+
RHSOfSelfRequirement = 1 << 1,
1091+
1092+
/// Include results that are members of protocols to which the contextual
1093+
/// type conforms.
1094+
AllowProtocolMembers = 1 << 2,
1095+
};
1096+
1097+
using DirectlyReferencedTypeLookupOptions =
1098+
OptionSet<DirectlyReferencedTypeLookupFlags>;
1099+
1100+
DirectlyReferencedTypeLookupOptions defaultDirectlyReferencedTypeLookupOptions =
1101+
DirectlyReferencedTypeLookupFlags::AllowProtocolMembers;
1102+
1103+
inline DirectlyReferencedTypeLookupOptions
1104+
operator|(DirectlyReferencedTypeLookupFlags flag1,
1105+
DirectlyReferencedTypeLookupFlags flag2) {
1106+
return DirectlyReferencedTypeLookupOptions(flag1) | flag2;
1107+
}
1108+
10851109
/// Retrieve the set of type declarations that are directly referenced from
10861110
/// the given parsed type representation.
10871111
static DirectlyReferencedTypeDecls
10881112
directReferencesForTypeRepr(Evaluator &evaluator, ASTContext &ctx,
10891113
TypeRepr *typeRepr, DeclContext *dc,
1090-
bool allowUsableFromInline,
1091-
bool rhsOfSelfRequirement,
1092-
bool allowProtocolMembers);
1114+
DirectlyReferencedTypeLookupOptions options);
10931115

10941116
/// Retrieve the set of type declarations that are directly referenced from
10951117
/// the given type.
@@ -1147,11 +1169,12 @@ SelfBounds SelfBoundsFromWhereClauseRequest::evaluate(
11471169
// Resolve the right-hand side.
11481170
DirectlyReferencedTypeDecls rhsDecls;
11491171
if (auto typeRepr = req.getConstraintRepr()) {
1172+
auto typeLookupOptions =
1173+
defaultDirectlyReferencedTypeLookupOptions |
1174+
DirectlyReferencedTypeLookupFlags::RHSOfSelfRequirement;
11501175
rhsDecls = directReferencesForTypeRepr(evaluator, ctx, typeRepr,
11511176
const_cast<DeclContext *>(dc),
1152-
/*allowUsableFromInline=*/false,
1153-
/*rhsOfSelfRequirement=*/true,
1154-
/*allowProtocolMembers=*/true);
1177+
typeLookupOptions);
11551178
}
11561179

11571180
SmallVector<ModuleDecl *, 2> modulesFound;
@@ -1213,10 +1236,9 @@ TypeDeclsFromWhereClauseRequest::evaluate(Evaluator &evaluator,
12131236

12141237
DirectlyReferencedTypeDecls result;
12151238
auto resolve = [&](TypeRepr *typeRepr) {
1216-
auto decls = directReferencesForTypeRepr(evaluator, ctx, typeRepr, ext,
1217-
/*allowUsableFromInline=*/false,
1218-
/*rhsOfSelfRequirement=*/false,
1219-
/*allowProtocolMembers=*/true);
1239+
auto decls =
1240+
directReferencesForTypeRepr(evaluator, ctx, typeRepr, ext,
1241+
defaultDirectlyReferencedTypeLookupOptions);
12201242
result.first.insert(result.first.end(),
12211243
decls.first.begin(),
12221244
decls.first.end());
@@ -2880,20 +2902,19 @@ resolveTypeDeclsToNominal(Evaluator &evaluator,
28802902
}
28812903

28822904
/// Perform unqualified name lookup for types at the given location.
2883-
static DirectlyReferencedTypeDecls
2884-
directReferencesForUnqualifiedTypeLookup(DeclNameRef name,
2885-
SourceLoc loc, DeclContext *dc,
2886-
LookupOuterResults lookupOuter,
2887-
bool allowUsableFromInline,
2888-
bool rhsOfSelfRequirement,
2889-
bool allowProtocolMembers) {
2905+
static DirectlyReferencedTypeDecls directReferencesForUnqualifiedTypeLookup(
2906+
DeclNameRef name, SourceLoc loc, DeclContext *dc,
2907+
LookupOuterResults lookupOuter,
2908+
DirectlyReferencedTypeLookupOptions typeLookupOptions) {
28902909
UnqualifiedLookupOptions options = UnqualifiedLookupFlags::TypeLookup;
2891-
if (allowProtocolMembers)
2892-
options |= UnqualifiedLookupFlags::AllowProtocolMembers;
2910+
if (typeLookupOptions.contains(
2911+
DirectlyReferencedTypeLookupFlags::AllowProtocolMembers))
2912+
options |= UnqualifiedLookupFlags::AllowProtocolMembers;
28932913
if (lookupOuter == LookupOuterResults::Included)
28942914
options |= UnqualifiedLookupFlags::IncludeOuterResults;
28952915

2896-
if (allowUsableFromInline)
2916+
if (typeLookupOptions.contains(
2917+
DirectlyReferencedTypeLookupFlags::AllowUsableFromInline))
28972918
options |= UnqualifiedLookupFlags::IncludeUsableFromInline;
28982919

28992920
// Manually exclude macro expansions here since the source location
@@ -2911,7 +2932,8 @@ directReferencesForUnqualifiedTypeLookup(DeclNameRef name,
29112932
// To avoid cycles when resolving the right-hand side, we perform the
29122933
// lookup in the parent context (for a protocol), or a special mode where
29132934
// we disregard 'Self' requirements (for a protocol extension).
2914-
if (rhsOfSelfRequirement) {
2935+
if (typeLookupOptions.contains(
2936+
DirectlyReferencedTypeLookupFlags::RHSOfSelfRequirement)) {
29152937
if (dc->getExtendedProtocolDecl())
29162938
options |= UnqualifiedLookupFlags::DisregardSelfBounds;
29172939
else {
@@ -2999,37 +3021,32 @@ directReferencesForQualifiedTypeLookup(Evaluator &evaluator,
29993021
}
30003022

30013023
/// Determine the types directly referenced by the given identifier type.
3002-
static DirectlyReferencedTypeDecls
3003-
directReferencesForDeclRefTypeRepr(Evaluator &evaluator, ASTContext &ctx,
3004-
DeclRefTypeRepr *repr, DeclContext *dc,
3005-
bool allowUsableFromInline,
3006-
bool rhsOfSelfRequirement,
3007-
bool allowProtocolMembers) {
3024+
static DirectlyReferencedTypeDecls directReferencesForDeclRefTypeRepr(
3025+
Evaluator &evaluator, ASTContext &ctx, DeclRefTypeRepr *repr,
3026+
DeclContext *dc, DirectlyReferencedTypeLookupOptions options) {
30083027
if (auto *qualIdentTR = dyn_cast<QualifiedIdentTypeRepr>(repr)) {
30093028
auto result = directReferencesForTypeRepr(
3010-
evaluator, ctx, qualIdentTR->getBase(), dc,
3011-
allowUsableFromInline, rhsOfSelfRequirement, allowProtocolMembers);
3029+
evaluator, ctx, qualIdentTR->getBase(), dc, options);
30123030

30133031
// For a qualified identifier, perform qualified name lookup.
30143032
result.first = directReferencesForQualifiedTypeLookup(
30153033
evaluator, ctx, result.first, repr->getNameRef(), dc, repr->getLoc(),
3016-
allowUsableFromInline);
3034+
options.contains(
3035+
DirectlyReferencedTypeLookupFlags::AllowUsableFromInline));
30173036

30183037
return result;
30193038
}
30203039

30213040
// For an unqualified identifier, perform unqualified name lookup.
30223041
return directReferencesForUnqualifiedTypeLookup(
30233042
repr->getNameRef(), repr->getLoc(), dc, LookupOuterResults::Excluded,
3024-
allowUsableFromInline, rhsOfSelfRequirement, allowProtocolMembers);
3043+
options);
30253044
}
30263045

30273046
static DirectlyReferencedTypeDecls
3028-
directReferencesForTypeRepr(Evaluator &evaluator,
3029-
ASTContext &ctx, TypeRepr *typeRepr,
3030-
DeclContext *dc, bool allowUsableFromInline,
3031-
bool rhsOfSelfRequirement,
3032-
bool allowProtocolMembers) {
3047+
directReferencesForTypeRepr(Evaluator &evaluator, ASTContext &ctx,
3048+
TypeRepr *typeRepr, DeclContext *dc,
3049+
DirectlyReferencedTypeLookupOptions options) {
30333050
DirectlyReferencedTypeDecls result;
30343051

30353052
switch (typeRepr->getKind()) {
@@ -3040,20 +3057,14 @@ directReferencesForTypeRepr(Evaluator &evaluator,
30403057
case TypeReprKind::Attributed: {
30413058
auto attributed = cast<AttributedTypeRepr>(typeRepr);
30423059
return directReferencesForTypeRepr(evaluator, ctx,
3043-
attributed->getTypeRepr(), dc,
3044-
allowUsableFromInline,
3045-
rhsOfSelfRequirement,
3046-
allowProtocolMembers);
3060+
attributed->getTypeRepr(), dc, options);
30473061
}
30483062

30493063
case TypeReprKind::Composition: {
30503064
auto composition = cast<CompositionTypeRepr>(typeRepr);
30513065
for (auto component : composition->getTypes()) {
30523066
auto componentResult =
3053-
directReferencesForTypeRepr(evaluator, ctx, component, dc,
3054-
allowUsableFromInline,
3055-
rhsOfSelfRequirement,
3056-
allowProtocolMembers);
3067+
directReferencesForTypeRepr(evaluator, ctx, component, dc, options);
30573068
result.first.insert(result.first.end(),
30583069
componentResult.first.begin(),
30593070
componentResult.first.end());
@@ -3066,11 +3077,8 @@ directReferencesForTypeRepr(Evaluator &evaluator,
30663077

30673078
case TypeReprKind::QualifiedIdent:
30683079
case TypeReprKind::UnqualifiedIdent:
3069-
return directReferencesForDeclRefTypeRepr(evaluator, ctx,
3070-
cast<DeclRefTypeRepr>(typeRepr),
3071-
dc, allowUsableFromInline,
3072-
rhsOfSelfRequirement,
3073-
allowProtocolMembers);
3080+
return directReferencesForDeclRefTypeRepr(
3081+
evaluator, ctx, cast<DeclRefTypeRepr>(typeRepr), dc, options);
30743082

30753083
case TypeReprKind::Dictionary:
30763084
result.first.push_back(ctx.getDictionaryDecl());
@@ -3079,11 +3087,8 @@ directReferencesForTypeRepr(Evaluator &evaluator,
30793087
case TypeReprKind::Tuple: {
30803088
auto tupleRepr = cast<TupleTypeRepr>(typeRepr);
30813089
if (tupleRepr->isParenType()) {
3082-
result = directReferencesForTypeRepr(evaluator, ctx,
3083-
tupleRepr->getElementType(0), dc,
3084-
allowUsableFromInline,
3085-
rhsOfSelfRequirement,
3086-
allowProtocolMembers);
3090+
result = directReferencesForTypeRepr(
3091+
evaluator, ctx, tupleRepr->getElementType(0), dc, options);
30873092
} else {
30883093
result.first.push_back(ctx.getBuiltinTupleDecl());
30893094
}
@@ -3092,40 +3097,28 @@ directReferencesForTypeRepr(Evaluator &evaluator,
30923097

30933098
case TypeReprKind::Vararg: {
30943099
auto packExpansionRepr = cast<VarargTypeRepr>(typeRepr);
3095-
return directReferencesForTypeRepr(evaluator, ctx,
3096-
packExpansionRepr->getElementType(), dc,
3097-
allowUsableFromInline,
3098-
rhsOfSelfRequirement,
3099-
allowProtocolMembers);
3100+
return directReferencesForTypeRepr(
3101+
evaluator, ctx, packExpansionRepr->getElementType(), dc, options);
31003102
}
31013103

31023104
case TypeReprKind::PackExpansion: {
31033105
auto packExpansionRepr = cast<PackExpansionTypeRepr>(typeRepr);
3104-
return directReferencesForTypeRepr(evaluator, ctx,
3105-
packExpansionRepr->getPatternType(), dc,
3106-
allowUsableFromInline,
3107-
rhsOfSelfRequirement,
3108-
allowProtocolMembers);
3106+
return directReferencesForTypeRepr(
3107+
evaluator, ctx, packExpansionRepr->getPatternType(), dc, options);
31093108
}
31103109

31113110
case TypeReprKind::PackElement: {
31123111
auto packReferenceRepr = cast<PackElementTypeRepr>(typeRepr);
3113-
return directReferencesForTypeRepr(evaluator, ctx,
3114-
packReferenceRepr->getPackType(), dc,
3115-
allowUsableFromInline,
3116-
rhsOfSelfRequirement,
3117-
allowProtocolMembers);
3112+
return directReferencesForTypeRepr(
3113+
evaluator, ctx, packReferenceRepr->getPackType(), dc, options);
31183114
}
31193115

31203116
case TypeReprKind::Inverse: {
31213117
// If ~P references a protocol P with a known inverse kind, record it in
31223118
// our set of inverses, otherwise just ignore it. We'll diagnose it later.
31233119
auto *inverseRepr = cast<InverseTypeRepr>(typeRepr);
3124-
auto innerResult = directReferencesForTypeRepr(evaluator, ctx,
3125-
inverseRepr->getConstraint(), dc,
3126-
allowUsableFromInline,
3127-
rhsOfSelfRequirement,
3128-
allowProtocolMembers);
3120+
auto innerResult = directReferencesForTypeRepr(
3121+
evaluator, ctx, inverseRepr->getConstraint(), dc, options);
31293122
if (innerResult.first.size() == 1) {
31303123
if (auto *proto = dyn_cast<ProtocolDecl>(innerResult.first[0])) {
31313124
if (auto ip = proto->getInvertibleProtocolKind()) {
@@ -3237,13 +3230,13 @@ DirectlyReferencedTypeDecls InheritedDeclsReferencedRequest::evaluate(
32373230
// If looking at a protocol's inheritance list,
32383231
// do not look at protocol members to avoid circularity.
32393232
// Protocols cannot inherit from any protocol members anyway.
3240-
bool allowProtocolMembers = (dc->getSelfProtocolDecl() == nullptr);
3233+
DirectlyReferencedTypeLookupOptions options;
3234+
if (dc->getSelfProtocolDecl() == nullptr) {
3235+
options |= DirectlyReferencedTypeLookupFlags::AllowProtocolMembers;
3236+
}
32413237

32423238
return directReferencesForTypeRepr(evaluator, dc->getASTContext(), typeRepr,
3243-
const_cast<DeclContext *>(dc),
3244-
/*allowUsableFromInline=*/false,
3245-
/*rhsOfSelfRequirement=*/false,
3246-
allowProtocolMembers);
3239+
const_cast<DeclContext *>(dc), options);
32473240
}
32483241

32493242
// Fall back to semantic types.
@@ -3261,11 +3254,9 @@ DirectlyReferencedTypeDecls UnderlyingTypeDeclsReferencedRequest::evaluate(
32613254
TypeAliasDecl *typealias) const {
32623255
// Prefer syntactic information when we have it.
32633256
if (auto typeRepr = typealias->getUnderlyingTypeRepr()) {
3264-
return directReferencesForTypeRepr(evaluator, typealias->getASTContext(),
3265-
typeRepr, typealias,
3266-
/*allowUsableFromInline=*/false,
3267-
/*rhsOfSelfRequirement=*/false,
3268-
/*allowProtocolMembers=*/true);
3257+
return directReferencesForTypeRepr(
3258+
evaluator, typealias->getASTContext(), typeRepr, typealias,
3259+
defaultDirectlyReferencedTypeLookupOptions);
32693260
}
32703261

32713262
// Fall back to semantic types.
@@ -3421,11 +3412,12 @@ ExtendedNominalRequest::evaluate(Evaluator &evaluator,
34213412
}
34223413

34233414
ASTContext &ctx = ext->getASTContext();
3424-
DirectlyReferencedTypeDecls referenced =
3425-
directReferencesForTypeRepr(evaluator, ctx, typeRepr, ext->getParent(),
3426-
ext->isInSpecializeExtensionContext(),
3427-
/*rhsOfSelfRequirement=*/false,
3428-
/*allowProtocolMembers=*/true);
3415+
auto options = defaultDirectlyReferencedTypeLookupOptions;
3416+
if (ext->isInSpecializeExtensionContext()) {
3417+
options |= DirectlyReferencedTypeLookupFlags::AllowUsableFromInline;
3418+
}
3419+
DirectlyReferencedTypeDecls referenced = directReferencesForTypeRepr(
3420+
evaluator, ctx, typeRepr, ext->getParent(), options);
34293421

34303422
// Resolve those type declarations to nominal type declarations.
34313423
SmallVector<ModuleDecl *, 2> modulesFound;
@@ -3473,10 +3465,8 @@ static bool declsAreProtocols(ArrayRef<TypeDecl *> decls) {
34733465

34743466
bool TypeRepr::isProtocolOrProtocolComposition(DeclContext *dc) {
34753467
auto &ctx = dc->getASTContext();
3476-
auto references = directReferencesForTypeRepr(ctx.evaluator, ctx, this, dc,
3477-
/*allowUsableFromInline=*/false,
3478-
/*rhsOfSelfRequirement=*/false,
3479-
/*allowProtocolMembers=*/true);
3468+
auto references = directReferencesForTypeRepr(
3469+
ctx.evaluator, ctx, this, dc, defaultDirectlyReferencedTypeLookupOptions);
34803470
return declsAreProtocols(references.first);
34813471
}
34823472

@@ -3506,13 +3496,9 @@ static GenericParamList *
35063496
createTupleExtensionGenericParams(ASTContext &ctx,
35073497
ExtensionDecl *ext,
35083498
TypeRepr *extendedTypeRepr) {
3509-
DirectlyReferencedTypeDecls referenced =
3510-
directReferencesForTypeRepr(ctx.evaluator, ctx,
3511-
extendedTypeRepr,
3512-
ext->getParent(),
3513-
/*allowUsableFromInline=*/false,
3514-
/*rhsOfSelfRequirement=*/false,
3515-
/*allowProtocolMembers=*/true);
3499+
DirectlyReferencedTypeDecls referenced = directReferencesForTypeRepr(
3500+
ctx.evaluator, ctx, extendedTypeRepr, ext->getParent(),
3501+
defaultDirectlyReferencedTypeLookupOptions);
35163502
assert(referenced.second.empty() && "Implement me");
35173503
if (referenced.first.size() != 1 || !isa<TypeAliasDecl>(referenced.first[0]))
35183504
return nullptr;
@@ -3784,11 +3770,9 @@ CustomAttrNominalRequest::evaluate(Evaluator &evaluator,
37843770
auto &ctx = dc->getASTContext();
37853771
DirectlyReferencedTypeDecls decls;
37863772
if (auto *typeRepr = attr->getTypeRepr()) {
3787-
decls = directReferencesForTypeRepr(
3788-
evaluator, ctx, typeRepr, dc,
3789-
/*allowUsableFromInline=*/false,
3790-
/*rhsOfSelfRequirement=*/false,
3791-
/*allowProtocolMembers=*/true);
3773+
decls =
3774+
directReferencesForTypeRepr(evaluator, ctx, typeRepr, dc,
3775+
defaultDirectlyReferencedTypeLookupOptions);
37923776
} else if (Type type = attr->getType()) {
37933777
decls = directReferencesForType(type);
37943778
}
@@ -3818,9 +3802,7 @@ CustomAttrNominalRequest::evaluate(Evaluator &evaluator,
38183802
anyObject = false;
38193803
decls = directReferencesForUnqualifiedTypeLookup(
38203804
name, loc, dc, LookupOuterResults::Included,
3821-
/*allowUsableFromInline=*/false,
3822-
/*rhsOfSelfRequirement=*/false,
3823-
/*allowProtocolMembers*/true);
3805+
defaultDirectlyReferencedTypeLookupOptions);
38243806
nominals = resolveTypeDeclsToNominal(evaluator, ctx, decls.first,
38253807
ResolveToNominalOptions(),
38263808
modulesFound, anyObject);
@@ -4056,11 +4038,8 @@ ProtocolDecl *ImplementsAttrProtocolRequest::evaluate(
40564038
auto typeRepr = attr->getProtocolTypeRepr();
40574039

40584040
ASTContext &ctx = dc->getASTContext();
4059-
DirectlyReferencedTypeDecls referenced =
4060-
directReferencesForTypeRepr(evaluator, ctx, typeRepr, dc,
4061-
/*allowUsableFromInline=*/false,
4062-
/*rhsOfSelfRequirement=*/false,
4063-
/*allowProtocolMembers=*/true);
4041+
DirectlyReferencedTypeDecls referenced = directReferencesForTypeRepr(
4042+
evaluator, ctx, typeRepr, dc, defaultDirectlyReferencedTypeLookupOptions);
40644043

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

0 commit comments

Comments
 (0)