Skip to content

Commit f003c49

Browse files
committed
[WIP] Disallow macro default argument with argument
Need to use variable from caller side context
1 parent 249a369 commit f003c49

12 files changed

+40
-95
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7523,11 +7523,15 @@ ERROR(extension_macro_invalid_conformance,none,
75237523
ERROR(macro_attached_to_invalid_decl,none,
75247524
"'%0' macro cannot be attached to %1 (%base2)",
75257525
(StringRef, DescriptiveDeclKind, const Decl *))
7526+
ERROR(conformance_macro,none,
7527+
"conformance macros are replaced by extension macros",
7528+
())
7529+
75267530
ERROR(macro_as_default_argument, none,
75277531
"non-built-in macro cannot be used as default argument",
75287532
())
7529-
ERROR(conformance_macro,none,
7530-
"conformance macros are replaced by extension macros",
7533+
ERROR(macro_as_default_argument_has_arguments, none,
7534+
"macro used as default argument cannot have arguments",
75317535
())
75327536

75337537
ERROR(macro_resolve_circular_reference, none,

include/swift/Basic/MacroRoles.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,6 @@ ATTACHED_MACRO_ROLE(Conformance, "conformance", "c")
7070
/// declarations in a code block.
7171
EXPERIMENTAL_FREESTANDING_MACRO_ROLE(CodeItem, "codeItem", CodeItemMacros)
7272

73-
/// A freestanding macro that is used as the default argument
74-
EXPERIMENTAL_FREESTANDING_MACRO_ROLE(DefaultArgument, "defaultArgument", ExpressionMacroDefaultArguments)
75-
7673
/// An attached macro that adds extensions to the declaration the
7774
/// macro is attached to.
7875
ATTACHED_MACRO_ROLE(Extension, "extension", "e")

lib/AST/ASTMangler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3877,7 +3877,6 @@ void ASTMangler::appendMacroExpansionContext(
38773877

38783878
case GeneratedSourceInfo::PrettyPrinted:
38793879
case GeneratedSourceInfo::ReplacedFunctionBody:
3880-
// TODO: ApolloZhu check if this correct?
38813880
case GeneratedSourceInfo::DefaultArgument:
38823881
return appendContext(origDC, StringRef());
38833882
}
@@ -3929,6 +3928,7 @@ void ASTMangler::appendMacroExpansionContext(
39293928

39303929
case GeneratedSourceInfo::PrettyPrinted:
39313930
case GeneratedSourceInfo::ReplacedFunctionBody:
3931+
case GeneratedSourceInfo::DefaultArgument:
39323932
llvm_unreachable("Exited above");
39333933
}
39343934

lib/AST/Module.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,8 @@ ModuleDecl::getOriginalLocation(SourceLoc loc) const {
920920
bufferID = SM.findBufferContainingLoc(loc);
921921
break;
922922
}
923+
case GeneratedSourceInfo::DefaultArgument:
924+
// TODO: ApolloZhu
923925
case GeneratedSourceInfo::ReplacedFunctionBody:
924926
// There's not really any "original" location for locations within
925927
// replaced function bodies. The body is actually different code to the

lib/AST/TypeCheckRequests.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2123,6 +2123,7 @@ UniqueUnderlyingTypeSubstitutionsRequest::evaluate(
21232123
switch (sf->Kind) {
21242124
case SourceFileKind::Interface:
21252125
case SourceFileKind::MacroExpansion:
2126+
case SourceFileKind::DefaultArgument:
21262127
case SourceFileKind::SIL:
21272128
return true;
21282129
case SourceFileKind::Main:

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,12 +1133,18 @@ Expr *DefaultArgumentExprRequest::evaluate(Evaluator &evaluator,
11331133
assert(initExpr);
11341134

11351135
// Prohibit default argument that is a non-built-in macro to avoid confusion,
1136-
// unless the experimental feature flag is set.
1137-
auto isMacroExpansionExpr = isa<MacroExpansionExpr>(initExpr);
1138-
if (isMacroExpansionExpr &&
1139-
!ctx.LangOpts.hasFeature(Feature::ExpressionMacroDefaultArguments)) {
1140-
ctx.Diags.diagnose(initExpr->getLoc(), diag::macro_as_default_argument);
1141-
return new (ctx) ErrorExpr(initExpr->getSourceRange(), ErrorType::get(ctx));
1136+
auto macroExpansionExpr = dyn_cast<MacroExpansionExpr>(initExpr);
1137+
if (macroExpansionExpr) {
1138+
// unless the experimental feature flag is set.
1139+
if (!ctx.LangOpts.hasFeature(Feature::ExpressionMacroDefaultArguments)) {
1140+
ctx.Diags.diagnose(initExpr->getLoc(), diag::macro_as_default_argument);
1141+
return new (ctx) ErrorExpr(initExpr->getSourceRange(), ErrorType::get(ctx));
1142+
}
1143+
auto args = macroExpansionExpr->getArgs();
1144+
if (!args->empty()) {
1145+
ctx.Diags.diagnose(args->getLoc(), diag::macro_as_default_argument_has_arguments);
1146+
return new (ctx) ErrorExpr(initExpr->getSourceRange(), ErrorType::get(ctx));
1147+
}
11421148
}
11431149

11441150
// If the param has an error type, there's no point type checking the default
@@ -1157,7 +1163,7 @@ Expr *DefaultArgumentExprRequest::evaluate(Evaluator &evaluator,
11571163
}
11581164

11591165
// Expression macro default arguments are checked at caller side
1160-
if (isMacroExpansionExpr)
1166+
if (macroExpansionExpr)
11611167
return initExpr;
11621168

11631169
// Walk the checked initializer and contextualize any closures

lib/Sema/TypeCheckExpr.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -774,8 +774,6 @@ static Expr *synthesizeCallerSideDefault(const ParamDecl *param,
774774
#include "swift/AST/MagicIdentifierKinds.def"
775775

776776
case DefaultArgumentKind::ExpressionMacro: {
777-
// FIXME: ApolloZhu what is macro has parameters that references
778-
// other things in decl context?
779777
SmallString<128> scratch;
780778
const StringRef text = param->getDefaultValueStringRepresentation(scratch);
781779
SourceFile *defaultArgSourceFile =

lib/Sema/TypeCheckStmt.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2819,6 +2819,7 @@ static bool requiresDefinition(Decl *decl) {
28192819
case SourceFileKind::Library:
28202820
case SourceFileKind::Main:
28212821
case SourceFileKind::MacroExpansion:
2822+
case SourceFileKind::DefaultArgument:
28222823
break;
28232824
}
28242825
}

test/Macros/Inputs/syntax_macro_definitions.swift

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2043,37 +2043,14 @@ public struct ClosureCallerMacro: ExpressionMacro {
20432043
}
20442044
}
20452045

2046-
public struct PrependHelloMacro: ExpressionMacro {
2046+
public struct PrependHelloToShadowedMacro: ExpressionMacro {
20472047
public static func expansion(
20482048
of node: some FreestandingMacroExpansionSyntax,
20492049
in context: some MacroExpansionContext
20502050
) -> ExprSyntax {
2051-
"""
2052-
"hello " + \(node.arguments.first!.expression)
2053-
"""
2054-
}
2055-
}
2056-
2057-
public struct AsIsMacro: ExpressionMacro {
2058-
public static func expansion(
2059-
of node: some FreestandingMacroExpansionSyntax,
2060-
in context: some MacroExpansionContext
2061-
) -> ExprSyntax {
2062-
node.arguments.first!.expression
2063-
}
2064-
}
2065-
2066-
public struct IntroduceShadowedMacro: ExpressionMacro {
2067-
public static func expansion(
2068-
of node: some FreestandingMacroExpansionSyntax,
2069-
in context: some MacroExpansionContext
2070-
) -> ExprSyntax {
2071-
"""
2072-
{
2073-
let shadowed = "from shadow"
2074-
return \(node.arguments.first!.expression)
2075-
}()
2076-
"""
2051+
#"""
2052+
"hello \(shadowed)"
2053+
"""#
20772054
}
20782055
}
20792056

test/Macros/Inputs/with_macro_default_arg_interface.swift

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,8 @@ public macro FileID<T: ExpressibleByStringLiteral>() -> T = #externalMacro(
44
)
55

66
@freestanding(expression)
7-
public macro PrependHello(_ param: String) -> String = #externalMacro(
8-
module: "MacroDefinition", type: "PrependHelloMacro"
9-
)
10-
11-
@freestanding(expression)
12-
public macro AsIs<T>(_ param: T) -> T = #externalMacro(
13-
module: "MacroDefinition", type: "AsIsMacro"
14-
)
15-
16-
@freestanding(expression)
17-
public macro IntroduceShadowed<T>(_ param: T) -> T = #externalMacro(
18-
module: "MacroDefinition", type: "IntroduceShadowedMacro"
7+
public macro PrependHelloToShadowed() -> String = #externalMacro(
8+
module: "MacroDefinition", type: "PrependHelloToShadowedMacro"
199
)
2010

2111
@freestanding(expression)
@@ -43,26 +33,8 @@ public struct ClosureCaller {
4333

4434
public let shadowed = "world"
4535

46-
public func testParameterUseVariableFromOriginalDeclContext(
47-
param: String = #PrependHello(shadowed)
48-
) {
49-
print(param)
50-
}
51-
52-
public func testMacroUseMacro(
53-
param: String = #PrependHello(#fileID)
54-
) {
55-
print(param)
56-
}
57-
58-
public func testUseShadowedFromOuterExpansion(
59-
param: String = #IntroduceShadowed(#PrependHello(shadowed))
60-
) {
61-
print(param)
62-
}
63-
64-
public func testNestedStillInOriginalDeclContext(
65-
param: String = #AsIs(#PrependHello(shadowed))
36+
public func preferVariableFromLocalScope(
37+
param: String = #PrependHelloToShadowed
6638
) {
6739
print(param)
6840
}

0 commit comments

Comments
 (0)