Skip to content

Commit 5c2faf3

Browse files
committed
[Macros] Don't expand macros inside macro expession arguments
Macro expressions nested in macro arguments should be type checked, but should not be expanded. rdar://108622244
1 parent ac218c2 commit 5c2faf3

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

lib/Sema/CSApply.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5389,7 +5389,15 @@ namespace {
53895389
E->setMacroRef(macroRef);
53905390
E->setType(expandedType);
53915391

5392-
if (!cs.Options.contains(ConstraintSystemFlags::DisableMacroExpansions)) {
5392+
// FIXME: Expansion should be lazy.
5393+
// i.e. 'ExpandMacroExpansionExprRequest' should be sinked into
5394+
// 'getRewritten()', and performed on-demand.
5395+
if (!cs.Options.contains(ConstraintSystemFlags::DisableMacroExpansions) &&
5396+
// Do not expand macros inside macro arguments. For example for
5397+
// '#stringify(#assert(foo))' when typechecking `#assert(foo)`,
5398+
// we don't want to expand it.
5399+
llvm::none_of(makeArrayRef(ExprStack).drop_back(1),
5400+
[](Expr *E) { return isa<MacroExpansionExpr>(E); })) {
53935401
(void)evaluateOrDefault(cs.getASTContext().evaluator,
53945402
ExpandMacroExpansionExprRequest{E}, None);
53955403
}

test/Macros/macro_expand.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,20 @@ func testDiscardableStringify(x: Int) {
179179
}
180180
#endif
181181

182+
#if TEST_DIAGNOSTICS
183+
// This causes an error when non-'Bool' value is passed.
184+
@freestanding(expression) macro assertAny<T>(_ value: T) = #externalMacro(module: "MacroDefinition", type: "AssertMacro")
185+
186+
func testNested() {
187+
struct Nested { }
188+
_ = #stringify(#assertAny(Nested()))
189+
// expected-note@-1 2 {{in expansion of macro 'stringify' here}}
190+
// CHECK-DIAGS-NOT: error: cannot convert value of type 'Nested' to expected argument type 'Bool'
191+
// CHECK-DIAGS: @__swiftmacro_9MacroUser10testNestedyyF9stringifyfMf_9assertAnyfMf_.swift:1:8: error: cannot convert value of type 'Nested' to expected argument type 'Bool'
192+
// CHECK-DIAGS-NOT: error: cannot convert value of type 'Nested' to expected argument type 'Bool'
193+
}
194+
#endif
195+
182196
func testStringifyWithThrows() throws {
183197
// Okay, we can put the try inside or outside
184198
_ = try #stringify(maybeThrowing())

0 commit comments

Comments
 (0)