Skip to content

Commit f78f572

Browse files
committed
Start requiring expression macros to be marked with @expression
1 parent 3e2bafc commit f78f572

File tree

11 files changed

+48
-35
lines changed

11 files changed

+48
-35
lines changed

include/swift/AST/Decl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8302,7 +8302,7 @@ class MissingMemberDecl : public Decl {
83028302
enum class MacroContext: uint8_t {
83038303
/// An expression macro, referenced explicitly via "#stringify" or similar
83048304
/// in the source code.
8305-
Expression,
8305+
Expression = 0x01,
83068306
};
83078307

83088308
/// The contexts in which a particular macro declaration can be used.

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6781,6 +6781,9 @@ WARNING(macro_type_access_warn,none,
67816781
(bool, AccessLevel, AccessLevel, bool))
67826782
ERROR(macro_in_nested,none,
67836783
"macro %0 can only be declared at file scope", (DeclName))
6784+
ERROR(macro_without_context,none,
6785+
"macro %0 must declare its applicable contexts (e.g., '@expression')",
6786+
(DeclName))
67846787

67856788
//------------------------------------------------------------------------------
67866789
// MARK: Move Only Errors

lib/AST/Decl.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9670,6 +9670,13 @@ SourceRange MacroDecl::getSourceRange() const {
96709670
return SourceRange(macroLoc, endLoc);
96719671
}
96729672

9673+
MacroContexts MacroDecl::getMacroContexts() const {
9674+
MacroContexts contexts = None;
9675+
if (getAttrs().hasAttribute<ExpressionAttr>())
9676+
contexts |= MacroContext::Expression;
9677+
return contexts;
9678+
}
9679+
96739680
SourceRange MacroExpansionDecl::getSourceRange() const {
96749681
SourceLoc endLoc;
96759682
if (ArgList)

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2000,6 +2000,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
20002000

20012001
if (!MD->getDeclContext()->isModuleScopeContext())
20022002
MD->diagnose(diag::macro_in_nested, MD->getName());
2003+
if (!MD->getMacroContexts())
2004+
MD->diagnose(diag::macro_without_context, MD->getName());
20032005
}
20042006

20052007
void visitMacroExpansionDecl(MacroExpansionDecl *MED) {

test/Macros/macro_availability_macosx.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
@available(macOS 12.0, *)
55
struct X { }
66

7-
macro m1: X = A.B // expected-error{{'X' is only available in macOS 12.0 or newer}}
7+
@expression macro m1: X = A.B // expected-error{{'X' is only available in macOS 12.0 or newer}}
88

99
@available(macOS 12.0, *)
10-
macro m2: X = A.B
10+
@expression macro m2: X = A.B

test/Macros/macro_expand.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
// FIXME: Swift parser is not enabled on Linux CI yet.
1010
// REQUIRES: OS=macosx
1111

12-
macro customFileID: String = MacroDefinition.FileIDMacro
13-
macro stringify<T>(_ value: T) -> (T, String) = MacroDefinition.StringifyMacro
14-
macro fileID<T: _ExpressibleByStringLitera>: T = MacroDefinition.FileIDMacro
12+
@expression macro customFileID: String = MacroDefinition.FileIDMacro
13+
@expression macro stringify<T>(_ value: T) -> (T, String) = MacroDefinition.StringifyMacro
14+
@expression macro fileID<T: _ExpressibleByStringLitera>: T = MacroDefinition.FileIDMacro
1515

1616
func testFileID(a: Int, b: Int) {
1717
// CHECK: MacroUser/macro_expand.swift
@@ -48,7 +48,7 @@ func testStringify(a: Int, b: Int) {
4848
// CHECK: (2, "a + b")
4949
testStringify(a: 1, b: 1)
5050

51-
macro addBlocker<T>(_ value: T) -> T = MacroDefinition.AddBlocker
51+
@expression macro addBlocker<T>(_ value: T) -> T = MacroDefinition.AddBlocker
5252

5353
struct OnlyAdds {
5454
static func +(lhs: OnlyAdds, rhs: OnlyAdds) -> OnlyAdds { lhs }

test/Macros/macros_diagnostics.swift

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,38 @@
33
// RUN: %target-typecheck-verify-swift -enable-experimental-feature Macros -module-name MacrosTest -load-plugin-library %t/%target-library-name(MacroDefinition) -I %swift-host-lib-dir
44
// REQUIRES: OS=macosx
55

6-
// REQUIRES: rdar103606300
6+
// REQUIRES: executable_test
77

8-
macro stringify<T>(_ value: T) -> (T, String) = MacroDefinition.StringifyMacro
9-
macro missingMacro1(_: Any) = MissingModule.MissingType // expected-note{{'missingMacro1' declared here}}
10-
macro missingMacro2(_: Any) = MissingModule.MissingType
8+
@expression macro stringify<T>(_ value: T) -> (T, String) = MacroDefinition.StringifyMacro
9+
@expression macro missingMacro1(_: Any) = MissingModule.MissingType // expected-note{{'missingMacro1' declared here}}
10+
@expression macro missingMacro2(_: Any) = MissingModule.MissingType
1111

1212
protocol P { }
1313

14-
macro tryToHide<T: P>(_: P) -> some P = BuiltinMacros.Blah
14+
@expression macro tryToHide<T: P>(_: P) -> some P = BuiltinMacros.Blah
1515
// expected-error@-1{{some' types are only permitted in properties, subscripts, and functions}}
1616

1717
internal struct X { } // expected-note{{type declared here}}
1818

19-
public macro createAnX: X = BuiltinMacros.Blah
19+
@expression public macro createAnX: X = BuiltinMacros.Blah
2020
// expected-error@-1{{macro cannot be declared public because its result type uses an internal type}}
2121

22-
macro m1: Int = A.B
23-
macro m1: Float = A.B
22+
@expression macro m1: Int = A.B
23+
@expression macro m1: Float = A.B
2424

25-
macro m2: Int = A.B // expected-note{{'m2' previously declared here}}
26-
macro m2: Int = A.B // expected-error{{invalid redeclaration of 'm2'}}
25+
@expression macro m2: Int = A.B // expected-note{{'m2' previously declared here}}
26+
@expression macro m2: Int = A.B // expected-error{{invalid redeclaration of 'm2'}}
2727

28-
macro m3(_: Int) -> Int = A.B
29-
macro m3(_: Int) -> Float = A.B
28+
@expression macro m3(_: Int) -> Int = A.B
29+
@expression macro m3(_: Int) -> Float = A.B
3030

31-
macro m4(_: Int) -> Int = A.B // expected-note{{'m4' previously declared here}}
32-
macro m4(_: Int) -> Int = A.B // expected-error{{invalid redeclaration of 'm4'}}
31+
@expression macro m4(_: Int) -> Int = A.B // expected-note{{'m4' previously declared here}}
32+
@expression macro m4(_: Int) -> Int = A.B // expected-error{{invalid redeclaration of 'm4'}}
3333

3434
struct ZZZ {
3535
macro m5: Int = A.B
3636
// expected-error@-1{{macro 'm5' can only be declared at file scope}}
37+
// expected-error@-2{{macro 'm5' must declare its applicable contexts (e.g., '@expression')}}
3738
}
3839

3940
func test(a: Int, b: Int) {

test/Macros/parsing.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
protocol P { }
33
protocol Q { associatedtype Assoc }
44

5-
macro m1: Int = A.M1
6-
macro m2(_: Int) = A.M2
7-
macro m3(a b: Int) -> Int = A.M3
8-
macro m4<T: Q>: T = A.M4 where T.Assoc: P
9-
macro m5<T: P>(_: T) = A.M4
5+
@expression macro m1: Int = A.M1
6+
@expression macro m2(_: Int) = A.M2
7+
@expression macro m3(a b: Int) -> Int = A.M3
8+
@expression macro m4<T: Q>: T = A.M4 where T.Assoc: P
9+
@expression macro m5<T: P>(_: T) = A.M4
1010

11-
macro m6 = A // expected-error{{expected '(' for macro parameters or ':' for a value-like macro}}
11+
@expression macro m6 = A // expected-error{{expected '(' for macro parameters or ':' for a value-like macro}}
1212
// expected-error@-1{{expected '.' between external macro module and type name}}
1313
// expected-error@-2{{expected external macro type name}}

test/ModuleInterface/macros.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
// RUN: %target-swift-frontend -compile-module-from-interface %t/Macros.swiftinterface -o %t/Macros.swiftmodule
88

99
// CHECK: #if compiler(>=5.3) && $Macros
10-
// CHECK-NEXT: public macro publicStringify<T>(_ value: T) -> (T, Swift.String) = SomeModule.StringifyMacro
10+
// CHECK-NEXT: @expression public macro publicStringify<T>(_ value: T) -> (T, Swift.String) = SomeModule.StringifyMacro
1111
// CHECK-NEXT: #endif
12-
public macro publicStringify<T>(_ value: T) -> (T, String) = SomeModule.StringifyMacro
12+
@expression public macro publicStringify<T>(_ value: T) -> (T, String) = SomeModule.StringifyMacro
1313

1414
// CHECK: #if compiler(>=5.3) && $Macros
15-
// CHECK: public macro publicLine<T>: T = SomeModule.Line where T : Swift.ExpressibleByIntegerLiteral
15+
// CHECK: @expression public macro publicLine<T>: T = SomeModule.Line where T : Swift.ExpressibleByIntegerLiteral
1616
// CHECK-NEXT: #endif
17-
public macro publicLine<T: ExpressibleByIntegerLiteral>: T = SomeModule.Line
17+
@expression public macro publicLine<T: ExpressibleByIntegerLiteral>: T = SomeModule.Line
1818

1919
// CHECK-NOT: internalStringify
20-
macro internalStringify<T>(_ value: T) -> (T, String) = SomeModule.StringifyMacro
20+
@expression macro internalStringify<T>(_ value: T) -> (T, String) = SomeModule.StringifyMacro
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
public macro publicStringify<T>(_ value: T) -> (T, String) = SomeModule.StringifyMacro
1+
@expression public macro publicStringify<T>(_ value: T) -> (T, String) = SomeModule.StringifyMacro
22

3-
macro internalStringify<T>(_ value: T) -> (T, String) = SomeModule.StringifyMacro
3+
@expression macro internalStringify<T>(_ value: T) -> (T, String) = SomeModule.StringifyMacro

0 commit comments

Comments
 (0)