Skip to content

Commit ef48b51

Browse files
committed
[Macros] Fix lookup of macro-produced variables
Calling `getInnermostDeclContext()->getParentSourceFile()` on a macro-produced decl does not seem to be a reliable way to obtain the macro expansion source file, because `PatternBindingDecl` is not a `DeclContext` and `getInnermostDeclContext()` falls back outside the macro expansion file. This patch switches to using `getSourceFileContainingLocation` instead. Resolves rdar://109376568.
1 parent 96cbc01 commit ef48b51

File tree

7 files changed

+51
-4
lines changed

7 files changed

+51
-4
lines changed

lib/AST/Decl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10333,9 +10333,10 @@ void MissingDecl::forEachMacroExpandedDecl(MacroExpandedDeclCallback callback) {
1033310333
auto *baseDecl = unexpandedMacro.baseDecl;
1033410334
if (!macroRef || !baseDecl)
1033510335
return;
10336+
auto *module = getModuleContext();
1033610337

1033710338
baseDecl->visitAuxiliaryDecls([&](Decl *auxiliaryDecl) {
10338-
auto *sf = auxiliaryDecl->getInnermostDeclContext()->getParentSourceFile();
10339+
auto *sf = module->getSourceFileContainingLocation(auxiliaryDecl->getLoc());
1033910340
// We only visit auxiliary decls that are macro expansions associated with
1034010341
// this macro reference.
1034110342
if (auto *med = macroRef.dyn_cast<MacroExpansionDecl *>()) {

lib/AST/DeclContext.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1040,7 +1040,8 @@ void IterableDeclContext::addMemberSilently(Decl *member, Decl *hint,
10401040
return;
10411041

10421042
// Synthesized member macros can add new members in a macro expansion buffer.
1043-
auto *memberSourceFile = member->getInnermostDeclContext()->getParentSourceFile();
1043+
auto *memberSourceFile = member->getModuleContext()
1044+
->getSourceFileContainingLocation(member->getLoc());
10441045
if (memberSourceFile->getFulfilledMacroRole() == MacroRole::Member ||
10451046
memberSourceFile->getFulfilledMacroRole() == MacroRole::Peer)
10461047
return;

test/Macros/Inputs/freestanding_macro_library.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@ public macro bitwidthNumberedStructs(_ baseName: String) = #externalMacro(module
1212

1313
@freestanding(expression)
1414
public macro stringify<T>(_ value: T) -> (T, String) = #externalMacro(module: "MacroDefinition", type: "StringifyMacro")
15+
16+
@freestanding(declaration, names: named(value))
17+
public macro varValue() = #externalMacro(module: "MacroDefinition", type: "VarValueMacro")

test/Macros/Inputs/macro_library.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,6 @@ public macro addCompletionHandler() = #externalMacro(module: "MacroDefinition",
3838

3939
@attached(peer, names: suffixed(Builder))
4040
public macro AddClassReferencingSelf() = #externalMacro(module: "MacroDefinition", type: "AddClassReferencingSelfMacro")
41+
42+
@attached(peer, names: named(value))
43+
public macro declareVarValuePeer() = #externalMacro(module: "MacroDefinition", type: "VarValueMacro")

test/Macros/Inputs/syntax_macro_definitions.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,3 +1413,24 @@ public struct MultiStatementClosure: ExpressionMacro {
14131413
"""
14141414
}
14151415
}
1416+
1417+
public struct VarValueMacro: DeclarationMacro, PeerMacro {
1418+
public static func expansion(
1419+
of macro: some FreestandingMacroExpansionSyntax,
1420+
in context: some MacroExpansionContext
1421+
) -> [DeclSyntax] {
1422+
return [
1423+
"var value: Int { 1 }"
1424+
]
1425+
}
1426+
1427+
public static func expansion(
1428+
of node: AttributeSyntax,
1429+
providingPeersOf declaration: some DeclSyntaxProtocol,
1430+
in context: some MacroExpansionContext
1431+
) throws -> [DeclSyntax] {
1432+
return [
1433+
"var value: Int { 1 }"
1434+
]
1435+
}
1436+
}

test/Macros/macro_expand_peers.swift

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import macro_library
3131
macro addCompletionHandler() = #externalMacro(module: "MacroDefinition", type: "AddCompletionHandler")
3232
@attached(peer, names: suffixed(Builder))
3333
macro AddClassReferencingSelf() = #externalMacro(module: "MacroDefinition", type: "AddClassReferencingSelfMacro")
34+
@attached(peer, names: named(value))
35+
macro declareVarValuePeer() = #externalMacro(module: "MacroDefinition", type: "VarValueMacro")
3436
#endif
3537

3638
@attached(peer, names: arbitrary)
@@ -166,8 +168,6 @@ struct S2 {
166168
macro myPropertyWrapper() =
167169
#externalMacro(module: "MacroDefinition", type: "PropertyWrapperMacro")
168170

169-
struct Date { }
170-
171171
struct MyWrapperThingy<T> {
172172
var storage: T
173173

@@ -192,3 +192,14 @@ struct S3 {
192192
self._x = MyWrapperThingy(storage: x)
193193
}
194194
}
195+
196+
@declareVarValuePeer
197+
struct Date {
198+
@declareVarValuePeer
199+
func foo() {}
200+
}
201+
202+
func testVarPeer() {
203+
_ = value
204+
_ = Date().value
205+
}

test/Macros/top_level_freestanding.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ macro anonymousTypes(public: Bool = false, _: () -> String) = #externalMacro(mod
3232
macro freestandingWithClosure<T>(_ value: T, body: (T) -> T) = #externalMacro(module: "MacroDefinition", type: "EmptyDeclarationMacro")
3333
@freestanding(declaration, names: arbitrary) macro bitwidthNumberedStructs(_ baseName: String) = #externalMacro(module: "MacroDefinition", type: "DefineBitwidthNumberedStructsMacro")
3434
@freestanding(expression) macro stringify<T>(_ value: T) -> (T, String) = #externalMacro(module: "MacroDefinition", type: "StringifyMacro")
35+
@freestanding(declaration, names: named(value)) macro varValue() = #externalMacro(module: "MacroDefinition", type: "VarValueMacro")
3536
#endif
3637

3738
// Test unqualified lookup from within a macro expansion
@@ -79,3 +80,9 @@ func testArbitraryAtGlobal() {
7980

8081
// DIAG_BUFFERS: @__swiftmacro_9MacroUser33_{{.*}}9stringifyfMf1_{{.*}}warning: 'deprecated()' is deprecated
8182
// DIAG_BUFFERS: @__swiftmacro_9MacroUser33_{{.*}}9stringifyfMf2_{{.*}}warning: 'deprecated()' is deprecated
83+
84+
#varValue
85+
86+
func testGlobalVariable() {
87+
_ = value
88+
}

0 commit comments

Comments
 (0)