Skip to content

Commit ebe0b63

Browse files
committed
[Module-scope lookup] Only inject macro-introduced operators at module scope
Well, this is fun. Due to the use of the module-scope lookup table to find operators, we need to carefully filter out any macro-introduced declarations that *aren't* operators when forming the module-scope lookup table. Otherwise, we can find macro-introduced static entities within types... from completely unrelated scopes. Fixes rdar://109219036.
1 parent 19ca63a commit ebe0b63

File tree

3 files changed

+69
-0
lines changed

3 files changed

+69
-0
lines changed

lib/AST/Module.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,13 @@ void SourceLookupCache::populateAuxiliaryDeclCache() {
403403
for (auto macroNames : introducedNames) {
404404
auto macroRef = macroNames.getFirst();
405405
for (auto name : macroNames.getSecond()) {
406+
407+
// If this macro isn't in a module-scope context, and the introduced
408+
// name isn't an operator, we shouldn't be able to see it.
409+
if (!decl->getDeclContext()->isModuleScopeContext() &&
410+
!name.getBaseName().isOperator())
411+
continue;
412+
406413
auto *placeholder = MissingDecl::forUnexpandedMacro(macroRef, decl);
407414
name.addToLookupTable(TopLevelAuxiliaryDecls, placeholder);
408415
}
@@ -485,6 +492,12 @@ void SourceLookupCache::lookupValue(DeclName Name, NLKind LookupKind,
485492
for (auto *unexpandedDecl : unexpandedDecls) {
486493
unexpandedDecl->forEachMacroExpandedDecl(
487494
[&](ValueDecl *decl) {
495+
// If the declaration is not a module-scope declaration, and
496+
// isn't an operator, ignore it.
497+
if (!decl->getDeclContext()->isModuleScopeContext() &&
498+
!decl->getName().getBaseName().isOperator())
499+
return;
500+
488501
if (decl->getName().matchesRef(Name)) {
489502
if (macroExpandedDecls.insert(decl).second)
490503
Result.push_back(decl);

test/Macros/Inputs/syntax_macro_definitions.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,3 +1531,25 @@ public struct UseIdentifierMacro: DeclarationMacro {
15311531
]
15321532
}
15331533
}
1534+
1535+
public struct StaticFooFuncMacro: DeclarationMacro {
1536+
public static func expansion(
1537+
of node: some FreestandingMacroExpansionSyntax,
1538+
in context: some MacroExpansionContext
1539+
) throws -> [DeclSyntax] {
1540+
return [
1541+
"static func foo() {}",
1542+
]
1543+
}
1544+
}
1545+
1546+
public struct SelfAlwaysEqualOperator: DeclarationMacro {
1547+
public static func expansion(
1548+
of node: some FreestandingMacroExpansionSyntax,
1549+
in context: some MacroExpansionContext
1550+
) throws -> [DeclSyntax] {
1551+
return [
1552+
"static func ==(lhs: Self, rhs: Bool) -> Bool { true }",
1553+
]
1554+
}
1555+
}

test/Macros/macro_expand.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,3 +425,37 @@ func testLocalVarsFromDeclarationMacros() {
425425
struct TakesVariadic {
426426
#emptyDecl("foo", "bar")
427427
}
428+
429+
// Funkiness with static functions introduced via macro expansions.
430+
@freestanding(declaration, names: named(foo())) public macro staticFooFunc() = #externalMacro(module: "MacroDefinition", type: "StaticFooFuncMacro")
431+
@freestanding(declaration, names: arbitrary) public macro staticFooFuncArbitrary() = #externalMacro(module: "MacroDefinition", type: "StaticFooFuncMacro")
432+
433+
class HasAnExpandedStatic {
434+
#staticFooFunc()
435+
}
436+
437+
class HasAnExpandedStatic2 {
438+
#staticFooFuncArbitrary()
439+
}
440+
441+
func testHasAnExpandedStatic() {
442+
#if TEST_DIAGNOSTICS
443+
foo() // expected-error{{cannot find 'foo' in scope}}
444+
#endif
445+
}
446+
447+
@freestanding(declaration, names: named(==)) public macro addSelfEqualsOperator() = #externalMacro(module: "MacroDefinition", type: "SelfAlwaysEqualOperator")
448+
@freestanding(declaration, names: arbitrary) public macro addSelfEqualsOperatorArbitrary() = #externalMacro(module: "MacroDefinition", type: "SelfAlwaysEqualOperator")
449+
450+
struct HasEqualsSelf {
451+
#addSelfEqualsOperator
452+
}
453+
454+
struct HasEqualsSelf2 {
455+
#addSelfEqualsOperatorArbitrary
456+
}
457+
458+
func testHasEqualsSelf(x: HasEqualsSelf, y: HasEqualsSelf2) {
459+
_ = (x == true)
460+
_ = (y == true)
461+
}

0 commit comments

Comments
 (0)