Skip to content

Commit 6b88070

Browse files
authored
Merge pull request #68782 from ApolloZhu/ApolloZhu/macro/diagnose-default-argument
[Macros] Disallow expression macro as default argument
2 parents c560267 + 35d5b68 commit 6b88070

File tree

4 files changed

+42
-1
lines changed

4 files changed

+42
-1
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7498,6 +7498,9 @@ ERROR(extension_macro_invalid_conformance,none,
74987498
ERROR(macro_attached_to_invalid_decl,none,
74997499
"'%0' macro cannot be attached to %1 (%base2)",
75007500
(StringRef, DescriptiveDeclKind, const Decl *))
7501+
ERROR(macro_as_default_argument, none,
7502+
"non-built-in macro cannot be used as default argument",
7503+
())
75017504
ERROR(conformance_macro,none,
75027505
"conformance macros are replaced by extension macros",
75037506
())

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,12 @@ Expr *DefaultArgumentExprRequest::evaluate(Evaluator &evaluator,
11141114
auto *initExpr = param->getStructuralDefaultExpr();
11151115
assert(initExpr);
11161116

1117+
// Prohibit default argument that is a non-built-in macro to avoid confusion.
1118+
if (isa<MacroExpansionExpr>(initExpr)) {
1119+
ctx.Diags.diagnose(initExpr->getLoc(), diag::macro_as_default_argument);
1120+
return new (ctx) ErrorExpr(initExpr->getSourceRange(), ErrorType::get(ctx));
1121+
}
1122+
11171123
// If the param has an error type, there's no point type checking the default
11181124
// expression, unless we are type checking for code completion, in which case
11191125
// the default expression might contain the code completion token.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// REQUIRES: swift_swift_parser
2+
3+
// RUN: %empty-directory(%t)
4+
// RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroDefinition) -module-name=MacroDefinition %S/Inputs/syntax_macro_definitions.swift -g -no-toolchain-stdlib-rpath
5+
6+
// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) %s
7+
8+
@freestanding(expression)
9+
macro MagicLine() -> Int = #externalMacro(module: "MacroDefinition", type: "MagicLineMacro")
10+
11+
struct LineContainer {
12+
let line: Int
13+
}
14+
15+
func partOfDefaultArgumentOkay(container: LineContainer = .init(line: #MagicLine)) {
16+
print(container.line)
17+
}
18+
19+
func parenthesizedExpansionAtDeclOkay(line: Int = (#MagicLine)) {
20+
print(line)
21+
}
22+
23+
func builtInOkay(line: Int = #line) {
24+
print(line)
25+
}
26+
27+
// expected-error@+1{{non-built-in macro cannot be used as default argument}}
28+
func asDefaultArgument(line: Int = #MagicLine) {
29+
print(line)
30+
}
31+
32+
asDefaultArgument()

test/ModuleInterface/unbuildable.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
// RUN: not %target-swift-frontend -typecheck-module-from-interface %t/UnbuildableCurrent.swiftinterface 2>&1 | %FileCheck -check-prefixes=ALL,CURRENT-VERIFY %s
2323
// RUN: not %target-swift-frontend -typecheck-module-from-interface %t/UnbuildableFuture.swiftinterface 2>&1 | %FileCheck -check-prefixes=ALL,FUTURE-VERIFY %s
2424

25-
// ALL: Unbuildable{{[^.]+}}.swiftinterface:{{[0-9]+}}:{{[0-9]+}}: error: no macro named 'somethingYouveNeverHeardOf'
25+
// ALL: Unbuildable{{[^.]+}}.swiftinterface:{{[0-9]+}}:{{[0-9]+}}: error: non-built-in macro cannot be used as default argument
2626

2727
#if CURRENT
2828
import UnbuildableCurrent

0 commit comments

Comments
 (0)