Skip to content

Commit

Permalink
[Macros] Disallow declaration of codeItem macros
Browse files Browse the repository at this point in the history
  • Loading branch information
ahoppen committed Apr 28, 2023
1 parent 186b854 commit becbdc8
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 2 deletions.
2 changes: 1 addition & 1 deletion include/swift/AST/DiagnosticsCommon.def
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ ERROR(unknown_attribute,none,
NOTE(in_macro_expansion,none,
"in expansion of macro %0 here", (DeclName))
ERROR(macro_experimental,none,
"%0 macros are an experimental feature that is not enabled (%1)",
"%0 macros are an experimental feature that is not enabled %select{|(%1)}1",
(StringRef, StringRef))
ERROR(ambiguous_macro_reference,none,
"ambiguous reference to macro %0", (DeclName))
Expand Down
3 changes: 3 additions & 0 deletions include/swift/AST/MacroDeclaration.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ bool isAttachedMacro(MacroRoles contexts);

MacroRoles getAttachedMacroRoles();

/// Checks if the macro is supported or guarded behind an experimental flag.
bool isMacroSupported(MacroRole role, ASTContext &ctx);

enum class MacroIntroducedDeclNameKind {
Named,
Overloaded,
Expand Down
15 changes: 15 additions & 0 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10182,6 +10182,21 @@ MacroRoles swift::getAttachedMacroRoles() {
return attachedMacroRoles;
}

bool swift::isMacroSupported(MacroRole role, ASTContext &ctx) {
switch (role) {
case MacroRole::Expression:
case MacroRole::Declaration:
case MacroRole::Accessor:
case MacroRole::MemberAttribute:
case MacroRole::Member:
case MacroRole::Peer:
case MacroRole::Conformance:
return true;
case MacroRole::CodeItem:
return ctx.LangOpts.hasFeature(Feature::CodeItemMacros);
}
}

void MissingDecl::forEachMacroExpandedDecl(MacroExpandedDeclCallback callback) {
auto macroRef = unexpandedMacro.macroRef;
auto *baseDecl = unexpandedMacro.baseDecl;
Expand Down
5 changes: 5 additions & 0 deletions lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2257,6 +2257,11 @@ Parser::parseMacroRoleAttribute(
status.setIsParseError();
return status;
}
if (!isMacroSupported(*role, Context)) {
diagnose(roleNameLoc, diag::macro_experimental, roleName.str(), "");
status.setIsParseError();
return status;
}

// Check that the role makes sense.
if (isAttached == !isAttachedMacro(*role)) {
Expand Down
4 changes: 4 additions & 0 deletions test/Macros/macro_codeitems_disabled.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// RUN: %target-typecheck-verify-swift -swift-version 5 %s

@freestanding(codeItem) // expected-error {{codeItem macros are an experimental feature that is not enabled}}
macro codeItems() // expected-error {{macro 'codeItems()' requires a definition}}
2 changes: 1 addition & 1 deletion test/Macros/macros_diagnostics.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// REQUIRES: swift_swift_parser

// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-experimental-feature FreestandingMacros -module-name MacrosTest
// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-experimental-feature FreestandingMacros -enable-experimental-feature CodeItemMacros -module-name MacrosTest

@expression macro stringify<T>(_ value: T) -> (T, String) = #externalMacro(module: "MacroDefinition", type: "StringifyMacro")
// expected-note@-1 2{{'stringify' declared here}}
Expand Down

0 comments on commit becbdc8

Please sign in to comment.