From 3c6d0bd7bbc590cb44b8656e82fcd6078720b888 Mon Sep 17 00:00:00 2001 From: Allan Shortlidge Date: Tue, 6 Aug 2024 15:53:52 -0700 Subject: [PATCH] AST: Refactor bool parameters of `directReferencesForTypeRepr()` into options. To make it easier to expand type lookup options, refactor the boolean arguments to `directReferencesForTypeRepr()` into a flags enum. NFC. --- lib/AST/NameLookup.cpp | 205 ++++++++++++++++++----------------------- 1 file changed, 92 insertions(+), 113 deletions(-) diff --git a/lib/AST/NameLookup.cpp b/lib/AST/NameLookup.cpp index 2c5b722e40a1c..6cb8569cb940c 100644 --- a/lib/AST/NameLookup.cpp +++ b/lib/AST/NameLookup.cpp @@ -1082,14 +1082,36 @@ namespace { }; } +enum class DirectlyReferencedTypeLookupFlags { + /// Include results that are `@inlinable` or `@usableFromInline`. + AllowUsableFromInline = 1 << 0, + + /// Discard 'Self' requirements in protocol extension `where` clauses. + RHSOfSelfRequirement = 1 << 1, + + /// Include results that are members of protocols to which the contextual + /// type conforms. + AllowProtocolMembers = 1 << 2, +}; + +using DirectlyReferencedTypeLookupOptions = + OptionSet; + +DirectlyReferencedTypeLookupOptions defaultDirectlyReferencedTypeLookupOptions = + DirectlyReferencedTypeLookupFlags::AllowProtocolMembers; + +inline DirectlyReferencedTypeLookupOptions +operator|(DirectlyReferencedTypeLookupFlags flag1, + DirectlyReferencedTypeLookupFlags flag2) { + return DirectlyReferencedTypeLookupOptions(flag1) | flag2; +} + /// Retrieve the set of type declarations that are directly referenced from /// the given parsed type representation. static DirectlyReferencedTypeDecls directReferencesForTypeRepr(Evaluator &evaluator, ASTContext &ctx, TypeRepr *typeRepr, DeclContext *dc, - bool allowUsableFromInline, - bool rhsOfSelfRequirement, - bool allowProtocolMembers); + DirectlyReferencedTypeLookupOptions options); /// Retrieve the set of type declarations that are directly referenced from /// the given type. @@ -1147,11 +1169,12 @@ SelfBounds SelfBoundsFromWhereClauseRequest::evaluate( // Resolve the right-hand side. DirectlyReferencedTypeDecls rhsDecls; if (auto typeRepr = req.getConstraintRepr()) { + auto typeLookupOptions = + defaultDirectlyReferencedTypeLookupOptions | + DirectlyReferencedTypeLookupFlags::RHSOfSelfRequirement; rhsDecls = directReferencesForTypeRepr(evaluator, ctx, typeRepr, const_cast(dc), - /*allowUsableFromInline=*/false, - /*rhsOfSelfRequirement=*/true, - /*allowProtocolMembers=*/true); + typeLookupOptions); } SmallVector modulesFound; @@ -1213,10 +1236,9 @@ TypeDeclsFromWhereClauseRequest::evaluate(Evaluator &evaluator, DirectlyReferencedTypeDecls result; auto resolve = [&](TypeRepr *typeRepr) { - auto decls = directReferencesForTypeRepr(evaluator, ctx, typeRepr, ext, - /*allowUsableFromInline=*/false, - /*rhsOfSelfRequirement=*/false, - /*allowProtocolMembers=*/true); + auto decls = + directReferencesForTypeRepr(evaluator, ctx, typeRepr, ext, + defaultDirectlyReferencedTypeLookupOptions); result.first.insert(result.first.end(), decls.first.begin(), decls.first.end()); @@ -2880,20 +2902,19 @@ resolveTypeDeclsToNominal(Evaluator &evaluator, } /// Perform unqualified name lookup for types at the given location. -static DirectlyReferencedTypeDecls -directReferencesForUnqualifiedTypeLookup(DeclNameRef name, - SourceLoc loc, DeclContext *dc, - LookupOuterResults lookupOuter, - bool allowUsableFromInline, - bool rhsOfSelfRequirement, - bool allowProtocolMembers) { +static DirectlyReferencedTypeDecls directReferencesForUnqualifiedTypeLookup( + DeclNameRef name, SourceLoc loc, DeclContext *dc, + LookupOuterResults lookupOuter, + DirectlyReferencedTypeLookupOptions typeLookupOptions) { UnqualifiedLookupOptions options = UnqualifiedLookupFlags::TypeLookup; - if (allowProtocolMembers) - options |= UnqualifiedLookupFlags::AllowProtocolMembers; + if (typeLookupOptions.contains( + DirectlyReferencedTypeLookupFlags::AllowProtocolMembers)) + options |= UnqualifiedLookupFlags::AllowProtocolMembers; if (lookupOuter == LookupOuterResults::Included) options |= UnqualifiedLookupFlags::IncludeOuterResults; - if (allowUsableFromInline) + if (typeLookupOptions.contains( + DirectlyReferencedTypeLookupFlags::AllowUsableFromInline)) options |= UnqualifiedLookupFlags::IncludeUsableFromInline; // Manually exclude macro expansions here since the source location @@ -2911,7 +2932,8 @@ directReferencesForUnqualifiedTypeLookup(DeclNameRef name, // To avoid cycles when resolving the right-hand side, we perform the // lookup in the parent context (for a protocol), or a special mode where // we disregard 'Self' requirements (for a protocol extension). - if (rhsOfSelfRequirement) { + if (typeLookupOptions.contains( + DirectlyReferencedTypeLookupFlags::RHSOfSelfRequirement)) { if (dc->getExtendedProtocolDecl()) options |= UnqualifiedLookupFlags::DisregardSelfBounds; else { @@ -2999,21 +3021,18 @@ directReferencesForQualifiedTypeLookup(Evaluator &evaluator, } /// Determine the types directly referenced by the given identifier type. -static DirectlyReferencedTypeDecls -directReferencesForDeclRefTypeRepr(Evaluator &evaluator, ASTContext &ctx, - DeclRefTypeRepr *repr, DeclContext *dc, - bool allowUsableFromInline, - bool rhsOfSelfRequirement, - bool allowProtocolMembers) { +static DirectlyReferencedTypeDecls directReferencesForDeclRefTypeRepr( + Evaluator &evaluator, ASTContext &ctx, DeclRefTypeRepr *repr, + DeclContext *dc, DirectlyReferencedTypeLookupOptions options) { if (auto *qualIdentTR = dyn_cast(repr)) { auto result = directReferencesForTypeRepr( - evaluator, ctx, qualIdentTR->getBase(), dc, - allowUsableFromInline, rhsOfSelfRequirement, allowProtocolMembers); + evaluator, ctx, qualIdentTR->getBase(), dc, options); // For a qualified identifier, perform qualified name lookup. result.first = directReferencesForQualifiedTypeLookup( evaluator, ctx, result.first, repr->getNameRef(), dc, repr->getLoc(), - allowUsableFromInline); + options.contains( + DirectlyReferencedTypeLookupFlags::AllowUsableFromInline)); return result; } @@ -3021,15 +3040,13 @@ directReferencesForDeclRefTypeRepr(Evaluator &evaluator, ASTContext &ctx, // For an unqualified identifier, perform unqualified name lookup. return directReferencesForUnqualifiedTypeLookup( repr->getNameRef(), repr->getLoc(), dc, LookupOuterResults::Excluded, - allowUsableFromInline, rhsOfSelfRequirement, allowProtocolMembers); + options); } static DirectlyReferencedTypeDecls -directReferencesForTypeRepr(Evaluator &evaluator, - ASTContext &ctx, TypeRepr *typeRepr, - DeclContext *dc, bool allowUsableFromInline, - bool rhsOfSelfRequirement, - bool allowProtocolMembers) { +directReferencesForTypeRepr(Evaluator &evaluator, ASTContext &ctx, + TypeRepr *typeRepr, DeclContext *dc, + DirectlyReferencedTypeLookupOptions options) { DirectlyReferencedTypeDecls result; switch (typeRepr->getKind()) { @@ -3040,20 +3057,14 @@ directReferencesForTypeRepr(Evaluator &evaluator, case TypeReprKind::Attributed: { auto attributed = cast(typeRepr); return directReferencesForTypeRepr(evaluator, ctx, - attributed->getTypeRepr(), dc, - allowUsableFromInline, - rhsOfSelfRequirement, - allowProtocolMembers); + attributed->getTypeRepr(), dc, options); } case TypeReprKind::Composition: { auto composition = cast(typeRepr); for (auto component : composition->getTypes()) { auto componentResult = - directReferencesForTypeRepr(evaluator, ctx, component, dc, - allowUsableFromInline, - rhsOfSelfRequirement, - allowProtocolMembers); + directReferencesForTypeRepr(evaluator, ctx, component, dc, options); result.first.insert(result.first.end(), componentResult.first.begin(), componentResult.first.end()); @@ -3066,11 +3077,8 @@ directReferencesForTypeRepr(Evaluator &evaluator, case TypeReprKind::QualifiedIdent: case TypeReprKind::UnqualifiedIdent: - return directReferencesForDeclRefTypeRepr(evaluator, ctx, - cast(typeRepr), - dc, allowUsableFromInline, - rhsOfSelfRequirement, - allowProtocolMembers); + return directReferencesForDeclRefTypeRepr( + evaluator, ctx, cast(typeRepr), dc, options); case TypeReprKind::Dictionary: result.first.push_back(ctx.getDictionaryDecl()); @@ -3079,11 +3087,8 @@ directReferencesForTypeRepr(Evaluator &evaluator, case TypeReprKind::Tuple: { auto tupleRepr = cast(typeRepr); if (tupleRepr->isParenType()) { - result = directReferencesForTypeRepr(evaluator, ctx, - tupleRepr->getElementType(0), dc, - allowUsableFromInline, - rhsOfSelfRequirement, - allowProtocolMembers); + result = directReferencesForTypeRepr( + evaluator, ctx, tupleRepr->getElementType(0), dc, options); } else { result.first.push_back(ctx.getBuiltinTupleDecl()); } @@ -3092,40 +3097,28 @@ directReferencesForTypeRepr(Evaluator &evaluator, case TypeReprKind::Vararg: { auto packExpansionRepr = cast(typeRepr); - return directReferencesForTypeRepr(evaluator, ctx, - packExpansionRepr->getElementType(), dc, - allowUsableFromInline, - rhsOfSelfRequirement, - allowProtocolMembers); + return directReferencesForTypeRepr( + evaluator, ctx, packExpansionRepr->getElementType(), dc, options); } case TypeReprKind::PackExpansion: { auto packExpansionRepr = cast(typeRepr); - return directReferencesForTypeRepr(evaluator, ctx, - packExpansionRepr->getPatternType(), dc, - allowUsableFromInline, - rhsOfSelfRequirement, - allowProtocolMembers); + return directReferencesForTypeRepr( + evaluator, ctx, packExpansionRepr->getPatternType(), dc, options); } case TypeReprKind::PackElement: { auto packReferenceRepr = cast(typeRepr); - return directReferencesForTypeRepr(evaluator, ctx, - packReferenceRepr->getPackType(), dc, - allowUsableFromInline, - rhsOfSelfRequirement, - allowProtocolMembers); + return directReferencesForTypeRepr( + evaluator, ctx, packReferenceRepr->getPackType(), dc, options); } case TypeReprKind::Inverse: { // If ~P references a protocol P with a known inverse kind, record it in // our set of inverses, otherwise just ignore it. We'll diagnose it later. auto *inverseRepr = cast(typeRepr); - auto innerResult = directReferencesForTypeRepr(evaluator, ctx, - inverseRepr->getConstraint(), dc, - allowUsableFromInline, - rhsOfSelfRequirement, - allowProtocolMembers); + auto innerResult = directReferencesForTypeRepr( + evaluator, ctx, inverseRepr->getConstraint(), dc, options); if (innerResult.first.size() == 1) { if (auto *proto = dyn_cast(innerResult.first[0])) { if (auto ip = proto->getInvertibleProtocolKind()) { @@ -3237,13 +3230,13 @@ DirectlyReferencedTypeDecls InheritedDeclsReferencedRequest::evaluate( // If looking at a protocol's inheritance list, // do not look at protocol members to avoid circularity. // Protocols cannot inherit from any protocol members anyway. - bool allowProtocolMembers = (dc->getSelfProtocolDecl() == nullptr); + DirectlyReferencedTypeLookupOptions options; + if (dc->getSelfProtocolDecl() == nullptr) { + options |= DirectlyReferencedTypeLookupFlags::AllowProtocolMembers; + } return directReferencesForTypeRepr(evaluator, dc->getASTContext(), typeRepr, - const_cast(dc), - /*allowUsableFromInline=*/false, - /*rhsOfSelfRequirement=*/false, - allowProtocolMembers); + const_cast(dc), options); } // Fall back to semantic types. @@ -3261,11 +3254,9 @@ DirectlyReferencedTypeDecls UnderlyingTypeDeclsReferencedRequest::evaluate( TypeAliasDecl *typealias) const { // Prefer syntactic information when we have it. if (auto typeRepr = typealias->getUnderlyingTypeRepr()) { - return directReferencesForTypeRepr(evaluator, typealias->getASTContext(), - typeRepr, typealias, - /*allowUsableFromInline=*/false, - /*rhsOfSelfRequirement=*/false, - /*allowProtocolMembers=*/true); + return directReferencesForTypeRepr( + evaluator, typealias->getASTContext(), typeRepr, typealias, + defaultDirectlyReferencedTypeLookupOptions); } // Fall back to semantic types. @@ -3421,11 +3412,12 @@ ExtendedNominalRequest::evaluate(Evaluator &evaluator, } ASTContext &ctx = ext->getASTContext(); - DirectlyReferencedTypeDecls referenced = - directReferencesForTypeRepr(evaluator, ctx, typeRepr, ext->getParent(), - ext->isInSpecializeExtensionContext(), - /*rhsOfSelfRequirement=*/false, - /*allowProtocolMembers=*/true); + auto options = defaultDirectlyReferencedTypeLookupOptions; + if (ext->isInSpecializeExtensionContext()) { + options |= DirectlyReferencedTypeLookupFlags::AllowUsableFromInline; + } + DirectlyReferencedTypeDecls referenced = directReferencesForTypeRepr( + evaluator, ctx, typeRepr, ext->getParent(), options); // Resolve those type declarations to nominal type declarations. SmallVector modulesFound; @@ -3473,10 +3465,8 @@ static bool declsAreProtocols(ArrayRef decls) { bool TypeRepr::isProtocolOrProtocolComposition(DeclContext *dc) { auto &ctx = dc->getASTContext(); - auto references = directReferencesForTypeRepr(ctx.evaluator, ctx, this, dc, - /*allowUsableFromInline=*/false, - /*rhsOfSelfRequirement=*/false, - /*allowProtocolMembers=*/true); + auto references = directReferencesForTypeRepr( + ctx.evaluator, ctx, this, dc, defaultDirectlyReferencedTypeLookupOptions); return declsAreProtocols(references.first); } @@ -3506,13 +3496,9 @@ static GenericParamList * createTupleExtensionGenericParams(ASTContext &ctx, ExtensionDecl *ext, TypeRepr *extendedTypeRepr) { - DirectlyReferencedTypeDecls referenced = - directReferencesForTypeRepr(ctx.evaluator, ctx, - extendedTypeRepr, - ext->getParent(), - /*allowUsableFromInline=*/false, - /*rhsOfSelfRequirement=*/false, - /*allowProtocolMembers=*/true); + DirectlyReferencedTypeDecls referenced = directReferencesForTypeRepr( + ctx.evaluator, ctx, extendedTypeRepr, ext->getParent(), + defaultDirectlyReferencedTypeLookupOptions); assert(referenced.second.empty() && "Implement me"); if (referenced.first.size() != 1 || !isa(referenced.first[0])) return nullptr; @@ -3784,11 +3770,9 @@ CustomAttrNominalRequest::evaluate(Evaluator &evaluator, auto &ctx = dc->getASTContext(); DirectlyReferencedTypeDecls decls; if (auto *typeRepr = attr->getTypeRepr()) { - decls = directReferencesForTypeRepr( - evaluator, ctx, typeRepr, dc, - /*allowUsableFromInline=*/false, - /*rhsOfSelfRequirement=*/false, - /*allowProtocolMembers=*/true); + decls = + directReferencesForTypeRepr(evaluator, ctx, typeRepr, dc, + defaultDirectlyReferencedTypeLookupOptions); } else if (Type type = attr->getType()) { decls = directReferencesForType(type); } @@ -3818,9 +3802,7 @@ CustomAttrNominalRequest::evaluate(Evaluator &evaluator, anyObject = false; decls = directReferencesForUnqualifiedTypeLookup( name, loc, dc, LookupOuterResults::Included, - /*allowUsableFromInline=*/false, - /*rhsOfSelfRequirement=*/false, - /*allowProtocolMembers*/true); + defaultDirectlyReferencedTypeLookupOptions); nominals = resolveTypeDeclsToNominal(evaluator, ctx, decls.first, ResolveToNominalOptions(), modulesFound, anyObject); @@ -4056,11 +4038,8 @@ ProtocolDecl *ImplementsAttrProtocolRequest::evaluate( auto typeRepr = attr->getProtocolTypeRepr(); ASTContext &ctx = dc->getASTContext(); - DirectlyReferencedTypeDecls referenced = - directReferencesForTypeRepr(evaluator, ctx, typeRepr, dc, - /*allowUsableFromInline=*/false, - /*rhsOfSelfRequirement=*/false, - /*allowProtocolMembers=*/true); + DirectlyReferencedTypeDecls referenced = directReferencesForTypeRepr( + evaluator, ctx, typeRepr, dc, defaultDirectlyReferencedTypeLookupOptions); // Resolve those type declarations to nominal type declarations. SmallVector modulesFound;