Handle module selectors in macro lookups

This commit is contained in:
Becca Royal-Gordon
2025-10-16 17:15:38 -07:00
parent f43bd72207
commit b35aaef526
5 changed files with 41 additions and 13 deletions

View File

@@ -8010,7 +8010,7 @@ ERROR(expected_macro_expansion_expr,PointsToFirstBadToken,
ERROR(expected_macro_expansion_decls,PointsToFirstBadToken,
"expected macro expansion to produce a declaration", ())
ERROR(macro_undefined,PointsToFirstBadToken,
"no macro named %0", (DeclName))
"no macro named %0", (DeclNameRef))
ERROR(external_macro_not_found,none,
"external macro implementation type '%0.%1' could not be found for "
"macro %2; %3", (StringRef, StringRef, DeclName, StringRef))

View File

@@ -1440,7 +1440,7 @@ namespace {
if (!protocol)
return Type();
auto macroIdent = ctx.getIdentifier(kind);
auto macroIdent = DeclNameRef(ctx.getIdentifier(kind));
auto macros = lookupMacros(Identifier(), macroIdent,
FunctionRefInfo::unappliedBaseName(),
MacroRole::Expression);
@@ -4111,12 +4111,12 @@ namespace {
/// Lookup all macros with the given macro name.
SmallVector<OverloadChoice, 1> lookupMacros(DeclName moduleName,
DeclName macroName,
DeclNameRef macroName,
FunctionRefInfo functionRefInfo,
MacroRoles roles) {
SmallVector<OverloadChoice, 1> choices;
auto results = namelookup::lookupMacros(CurDC, DeclNameRef(moduleName),
DeclNameRef(macroName), roles);
macroName, roles);
for (const auto &result : results) {
// Ignore invalid results. This matches the OverloadedDeclRefExpr
// logic.
@@ -4143,7 +4143,7 @@ namespace {
// Look up the macros with this name.
auto moduleIdent = expr->getModuleName().getBaseName();
auto macroIdent = expr->getMacroName().getBaseName();
auto macroIdent = expr->getMacroName().withoutArgumentLabels(ctx);
FunctionRefInfo functionRefInfo = FunctionRefInfo::singleBaseNameApply();
auto macros = lookupMacros(moduleIdent, macroIdent, functionRefInfo,
expr->getMacroRoles());

View File

@@ -1495,8 +1495,11 @@ static Type diagnoseUnknownType(const TypeResolution &resolution,
if (parentType.isNull()) {
// Tailored diagnostic for custom attributes.
if (resolution.getOptions().is(TypeResolverContext::CustomAttr)) {
diags.diagnose(repr->getNameLoc(), diag::unknown_attr_name,
repr->getNameRef().getBaseIdentifier().str());
SmallString<64> scratch;
llvm::raw_svector_ostream scratchOS(scratch);
repr->getNameRef().printPretty(scratchOS);
diags.diagnose(repr->getNameLoc(), diag::unknown_attr_name, scratch);
return ErrorType::get(ctx);
}
@@ -5171,9 +5174,13 @@ TypeResolver::resolveDeclRefTypeRepr(DeclRefTypeRepr *repr,
if (!options.contains(TypeResolutionFlags::SilenceErrors)) {
// Tailored diagnostic for custom attributes.
if (options.is(TypeResolverContext::CustomAttr)) {
SmallString<64> scratch;
llvm::raw_svector_ostream scratchOS(scratch);
repr->getNameRef().printPretty(scratchOS);
auto &ctx = resolution.getASTContext();
ctx.Diags.diagnose(repr->getNameLoc(), diag::unknown_attr_name,
repr->getNameRef().getBaseIdentifier().str());
scratch);
return ErrorType::get(ctx);
}

View File

@@ -40,3 +40,6 @@ public struct available {
public struct MyBuilder {
public static func buildBlock()
}
@freestanding(expression) public macro ExprMacro() -> String = #file
@attached(peer) public macro PeerMacro() = #externalMacro(module: "Fnord", type: "PeerMacro")

View File

@@ -11,7 +11,6 @@
// * Cross-import overlays
// * Key path dynamic member lookup
// * Custom type attributes (and coverage of type attrs generally is sparse)
// * Macros
//
// It also might not cover all combinations of name lookup paths and inputs.
@@ -58,6 +57,8 @@ extension A: @retroactive Swift::Equatable {
_ = \ModuleSelectorTestingKit::A.magnitude
_ = \A.ModuleSelectorTestingKit::magnitude
_ = #ModuleSelectorTestingKit::ExprMacro
}
// FIXME: Can we test @convention(witness_method:)?
@@ -124,8 +125,14 @@ extension B: @retroactive main::Equatable {
// FIXME improve: expected-error@-1 {{'main::A' in scope}} -- different diagnostic wording for legacy parser vs. ASTGen
_ = \A.main::magnitude
// FIXME improve: expected-error@-1 {{value of type 'A' has no member 'main::magnitude'}}
_ = #main::ExprMacro
// expected-error@-1 {{no macro named 'main::ExprMacro'}}
}
@main::PeerMacro func thingy() {}
// expected-error@-1 {{unknown attribute 'main::PeerMacro'}}
// FIXME: Can we test @convention(witness_method:)?
}
@@ -184,8 +191,13 @@ extension C: @retroactive ModuleSelectorTestingKit::Equatable {
_ = \ModuleSelectorTestingKit::A.magnitude
_ = \A.ModuleSelectorTestingKit::magnitude
_ = #ModuleSelectorTestingKit::ExprMacro
}
@ModuleSelectorTestingKit::PeerMacro func thingy() {}
// expected-error@-1 {{external macro implementation type 'Fnord.PeerMacro' could not be found for macro 'PeerMacro()'; plugin for module 'Fnord' not found}}
// FIXME: Can we test @convention(witness_method:)?
}
@@ -244,8 +256,14 @@ extension D: @retroactive Swift::Equatable {
// FIXME improve: expected-error@-1 {{'Swift::A' in scope}} -- different diagnostic wording for legacy parser vs. ASTGen
_ = \A.Swift::magnitude
// FIXME improve: expected-error@-1 {{value of type 'A' has no member 'Swift::magnitude'}}
_ = #Swift::ExprMacro
// expected-error@-1 {{no macro named 'Swift::ExprMacro'}}
}
@Swift::PeerMacro func thingy() {}
// expected-error@-1 {{unknown attribute 'Swift::PeerMacro'}}
// FIXME: Can we test @convention(witness_method:)?
}
@@ -262,25 +280,25 @@ struct AvailableUser {
@available(macOS 10.15, *) var use1: String { "foo" }
@main::available() var use2
// FIXME improve: expected-error@-1 {{unknown attribute 'available'}}
// FIXME improve: expected-error@-1 {{unknown attribute 'main::available'}}
// FIXME suppress: expected-error@-2 {{type annotation missing in pattern}}
@ModuleSelectorTestingKit::available() var use4
// no-error
@Swift::available() var use5
// FIXME improve: expected-error@-1 {{unknown attribute 'available'}}
// FIXME improve: expected-error@-1 {{unknown attribute 'Swift::available'}}
// FIXME suppress: expected-error@-2 {{type annotation missing in pattern}}
}
func builderUser2(@main::MyBuilder fn: () -> Void) {}
// FIXME improve: expected-error@-1 {{unknown attribute 'MyBuilder'}}
// FIXME improve: expected-error@-1 {{unknown attribute 'main::MyBuilder'}}
func builderUser3(@ModuleSelectorTestingKit::MyBuilder fn: () -> Void) {}
// no-error
func builderUser4(@Swift::MyBuilder fn: () -> Void) {}
// FIXME improve: expected-error@-1 {{unknown attribute 'MyBuilder'}}
// FIXME improve: expected-error@-1 {{unknown attribute 'Swift::MyBuilder'}}
// Error cases