Skip to content

Commit 9b9d576

Browse files
authored
Merge pull request #66526 from DougGregor/non-expression-macro-no-void
2 parents 330af0b + f7de3a3 commit 9b9d576

File tree

6 files changed

+30
-19
lines changed

6 files changed

+30
-19
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4811,16 +4811,14 @@ void PrintAST::visitMacroDecl(MacroDecl *decl) {
48114811
}
48124812
);
48134813

4814-
{
4814+
if (decl->resultType.getTypeRepr() ||
4815+
!decl->getResultInterfaceType()->isVoid()) {
48154816
Printer.printStructurePre(PrintStructureKind::DeclResultTypeClause);
48164817
SWIFT_DEFER {
48174818
Printer.printStructurePost(PrintStructureKind::DeclResultTypeClause);
48184819
};
48194820

4820-
if (decl->parameterList)
4821-
Printer << " -> ";
4822-
else
4823-
Printer << ": ";
4821+
Printer << " -> ";
48244822

48254823
TypeLoc resultTypeLoc(
48264824
decl->resultType.getTypeRepr(), decl->getResultInterfaceType());

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2072,15 +2072,25 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
20722072
}
20732073
}
20742074

2075-
// If the macro has a (non-Void) result type, it must have the freestanding
2075+
// If the macro has a result type, it must have the freestanding
20762076
// expression role. Other roles cannot have result types.
20772077
if (auto resultTypeRepr = MD->getResultTypeRepr()) {
2078-
if (!MD->getMacroRoles().contains(MacroRole::Expression) &&
2079-
!MD->getResultInterfaceType()->isEqual(Ctx.getVoidType())) {
2080-
auto resultType = MD->getResultInterfaceType();
2081-
Ctx.Diags.diagnose(
2082-
MD->arrowLoc, diag::macro_result_type_cannot_be_used, resultType)
2083-
.highlight(resultTypeRepr->getSourceRange());
2078+
if (!MD->getMacroRoles().contains(MacroRole::Expression)) {
2079+
auto resultType = MD->getResultInterfaceType(); {
2080+
auto diag = Ctx.Diags.diagnose(
2081+
MD->arrowLoc, diag::macro_result_type_cannot_be_used, resultType);
2082+
diag.highlight(resultTypeRepr->getSourceRange());
2083+
2084+
// In a .swiftinterface file, downgrade this diagnostic to a warning.
2085+
// This allows the compiler to process existing .swiftinterface
2086+
// files that contain this issue.
2087+
if (resultType->isVoid()) {
2088+
if (auto sourceFile = MD->getParentSourceFile())
2089+
if (sourceFile->Kind == SourceFileKind::Interface)
2090+
diag.limitBehavior(DiagnosticBehavior::Warning);
2091+
}
2092+
}
2093+
20842094
Ctx.Diags.diagnose(MD->arrowLoc, diag::macro_make_freestanding_expression)
20852095
.fixItInsert(MD->getAttributeInsertionLoc(false),
20862096
"@freestanding(expression)\n");

test/Macros/attached_macros_diags.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@
66
// expected-warning@-1{{external macro implementation type 'MyMacros.Macro1' could not be found for macro 'm1()'}}
77
// expected-note@-2{{'m1()' declared here}}
88

9-
@attached(accessor) macro m2(_: Int) -> Void = #externalMacro(module: "MyMacros", type: "Macro2")
9+
@attached(accessor) macro m2(_: Int) = #externalMacro(module: "MyMacros", type: "Macro2")
1010
// expected-warning@-1{{external macro implementation type 'MyMacros.Macro2' could not be found for macro 'm2'}}
1111
// expected-note@-2{{candidate has partially matching parameter list (Int)}}
1212
// expected-note@-3{{candidate expects value of type 'Int' for parameter #1 (got 'String')}}
1313

14-
@attached(accessor) macro m2(_: Double) -> Void = #externalMacro(module: "MyMacros", type: "Macro2")
14+
@attached(accessor) macro m2(_: Double) = #externalMacro(module: "MyMacros", type: "Macro2")
1515
// expected-warning@-1{{external macro implementation type 'MyMacros.Macro2' could not be found for macro 'm2'}}
1616
// expected-note@-2{{candidate has partially matching parameter list (Double)}}
1717
// expected-note@-3{{candidate expects value of type 'Double' for parameter #1 (got 'String')}}
1818

19-
@attached(accessor) macro m3(message: String) -> Void = #externalMacro(module: "MyMacros", type: "Macro3")
19+
@attached(accessor) macro m3(message: String) = #externalMacro(module: "MyMacros", type: "Macro3")
2020
// expected-warning@-1{{external macro implementation type 'MyMacros.Macro3' could not be found for macro 'm3(message:)'}}
2121

2222
@freestanding(expression) macro stringify<T>(_ value: T) -> (T, String) = #externalMacro(module: "MyMacros", type: "StringifyMacro")

test/Macros/macros_diagnostics.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ struct SomeType {
211211

212212
@freestanding(declaration) macro nonExpressionReturnsVoid<T>(_: T) -> Void = #externalMacro(module: "A", type: "B")
213213
// expected-warning@-1{{external macro implementation type}}
214+
// expected-error@-2{{only a freestanding expression macro can produce a result of type 'Void'}}
215+
// expected-note@-3{{make this macro a freestanding expression macro}}{{1-1=@freestanding(expression)\n}}
216+
// expected-note@-4{{remove the result type if the macro does not produce a value}}{{68-76=}}
214217

215218

216219
@freestanding(expression)

test/Macros/parsing.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ macro am1()
5151
named, // expected-error{{introduced name kind 'named' requires a single argument '(name)'}}
5252
arbitrary(a) // expected-error{{introduced name kind 'arbitrary' must not have an argument}}
5353
)
54-
macro am2() -> Void
54+
macro am2()
5555
// expected-error@-1{{macro 'am2()' requires a definition}}
5656

5757
#m1 + 1

test/ModuleInterface/macros.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@
3030
@freestanding(expression) public macro publicLine<T: ExpressibleByIntegerLiteral>() -> T = #externalMacro(module: "SomeModule", type: "Line")
3131

3232
// CHECK: #if compiler(>=5.3) && $Macros
33-
// CHECK: @attached(accessor) public macro myWrapper() -> () = #externalMacro(module: "SomeModule", type: "Wrapper")
33+
// CHECK: @attached(accessor) public macro myWrapper() = #externalMacro(module: "SomeModule", type: "Wrapper")
3434
// CHECK-NEXT: #endif
3535
@attached(accessor) public macro myWrapper() = #externalMacro(module: "SomeModule", type: "Wrapper")
3636

3737
// CHECK: #if compiler(>=5.3) && $Macros && $AttachedMacros
38-
// CHECK: @attached(member, names: named(`init`), prefixed(`$`)) public macro MemberwiseInit() -> () = #externalMacro(module: "SomeModule", type: "MemberwiseInitMacro")
38+
// CHECK: @attached(member, names: named(`init`), prefixed(`$`)) public macro MemberwiseInit() = #externalMacro(module: "SomeModule", type: "MemberwiseInitMacro")
3939
// CHECK-NEXT: #endif
40-
@attached(member, names: named(init), prefixed(`$`)) public macro MemberwiseInit() -> () = #externalMacro(module: "SomeModule", type: "MemberwiseInitMacro")
40+
@attached(member, names: named(init), prefixed(`$`)) public macro MemberwiseInit() = #externalMacro(module: "SomeModule", type: "MemberwiseInitMacro")
4141

4242
// CHECK-NOT: internalStringify
4343
@freestanding(expression) macro internalStringify<T>(_ value: T) -> (T, String) = #externalMacro(module: "SomeModule", type: "StringifyMacro")

0 commit comments

Comments
 (0)