-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rustc: Tweak custom attribute capabilities #50120
Conversation
21ad04d
to
de1e1a7
Compare
src/libsyntax/ext/expand.rs
Outdated
@@ -539,6 +541,45 @@ impl<'a, 'b> MacroExpander<'a, 'b> { | |||
} | |||
} | |||
|
|||
fn extract_proc_macro_attr_input(&self, tokens: TokenStream, span: Span) -> TokenStream { | |||
match tokens.trees().next() { | |||
Some(TokenTree::Delimited(_, delim)) => delim.tts.into(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still accepts #[attr(delimited token stream) + anything else]
.
Could you add a test making sure that the example above and also #[attr = "something"]
are rejected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aha excellent point, tests added and fixed
ExpansionKind::Items => return, | ||
ExpansionKind::TraitItems => return, | ||
ExpansionKind::ImplItems => return, | ||
ExpansionKind::ForeignItems => return, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if a proc macro attribute is applied to something else, like match
arm (match 0 { #[attr] _ => {} }
), or a generic parameter (fn f<#[attr] T>
), or enum variant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect it already produces some kind of error, but it would be good to have a test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting! Turns out we don't expand procedural macros in those locations right now so you get an "unknown attribute" error. I've added a test to ensure it's at least an error.
This commit starts to lay some groundwork for the stabilization of custom attribute invocations and general procedural macros. It applies a number of changes discussed on [internals] as well as a [recent issue][issue], namely: * The path used to specify a custom attribute must be of length one and cannot be a global path. This'll help future-proof us against any ambiguities and give us more time to settle the precise syntax. In the meantime though a bare identifier can be used and imported to invoke a custom attribute macro. A new feature gate, `proc_macro_path_invoc`, was added to gate multi-segment paths and absolute paths. * The set of items which can be annotated by a custom procedural attribute has been restricted. Statements, expressions, and modules are disallowed behind two new feature gates: `proc_macro_expr` and `proc_macro_mod`. * The input to procedural macro attributes has been restricted and adjusted. Today an invocation like `#[foo(bar)]` will receive `(bar)` as the input token stream, but after this PR it will only receive `bar` (the delimiters were removed). Invocations like `#[foo]` are still allowed and will be invoked in the same way as `#[foo()]`. This is a **breaking change** for all nightly users as the syntax coming in to procedural macros will be tweaked slightly. * Procedural macros (`foo!()` style) can only be expanded to item-like items by default. A separate feature gate, `proc_macro_non_items`, is required to expand to items like expressions, statements, etc. Closes rust-lang#50038 [internals]: https://internals.rust-lang.org/t/help-stabilize-a-subset-of-macros-2-0/7252 [issue]: rust-lang#50038
de1e1a7
to
79630d4
Compare
Updated! |
@bors r+ |
📌 Commit 79630d4 has been approved by |
…nkov rustc: Tweak custom attribute capabilities This commit starts to lay some groundwork for the stabilization of custom attribute invocations and general procedural macros. It applies a number of changes discussed on [internals] as well as a [recent issue][issue], namely: * The path used to specify a custom attribute must be of length one and cannot be a global path. This'll help future-proof us against any ambiguities and give us more time to settle the precise syntax. In the meantime though a bare identifier can be used and imported to invoke a custom attribute macro. A new feature gate, `proc_macro_path_invoc`, was added to gate multi-segment paths and absolute paths. * The set of items which can be annotated by a custom procedural attribute has been restricted. Statements, expressions, and modules are disallowed behind two new feature gates: `proc_macro_expr` and `proc_macro_mod`. * The input to procedural macro attributes has been restricted and adjusted. Today an invocation like `#[foo(bar)]` will receive `(bar)` as the input token stream, but after this PR it will only receive `bar` (the delimiters were removed). Invocations like `#[foo]` are still allowed and will be invoked in the same way as `#[foo()]`. This is a **breaking change** for all nightly users as the syntax coming in to procedural macros will be tweaked slightly. * Procedural macros (`foo!()` style) can only be expanded to item-like items by default. A separate feature gate, `proc_macro_non_items`, is required to expand to items like expressions, statements, etc. Closes #50038 [internals]: https://internals.rust-lang.org/t/help-stabilize-a-subset-of-macros-2-0/7252 [issue]: #50038
☀️ Test successful - status-appveyor, status-travis |
Tested on commit rust-lang/rust@222551f. Direct link to PR: <rust-lang/rust#50120> 💔 clippy-driver on windows: test-pass → test-fail (cc @Manishearth @llogiq @mcarton @oli-obk). 💔 clippy-driver on linux: test-pass → test-fail (cc @Manishearth @llogiq @mcarton @oli-obk).
What's the motivation for this change? The previous behaviour was intentional and spec'ed in the RFC. What's the long-term plan for handling delimiters? |
@nrc most of the discussion happend in #50038 with the tl;dr; (as I understand it) as:
Does that make sense? @petrochenkov may be better able to fill in some holes as well. |
The |
This seems to break crates that are using #![feature(use_extern_macros)] and invoking them like this:
Is that intended? |
Ah oops yes indeed! I don't think that bang-style macros have the same ambiguity with attribute-related macros, so we should be able to unambiguously allow path-like invocations of bang macros (both @jcsoo or @SergioBenitez want to file a bug to track this? |
@alexcrichton Submitted a PR instead: #50295 |
Don't feature gate bang macros on 'proc_macro_path_invoc'. Fixes oversight from #50120.
After rust-lang/rust#50120 procedural macros do not receive the parentheses as part of their attributes TokenStream. Also the proc_macro_non_items feature is necessary to use async_block.
After rust-lang/rust#50120 procedural macros do not receive the parentheses as part of their attributes TokenStream. Also the proc_macro_non_items feature is necessary to use async_block.
After rust-lang/rust#50120 procedural macros do not receive the parentheses as part of their attributes TokenStream. Also the proc_macro_non_items feature is necessary to use async_block.
After rust-lang/rust#50120 procedural macros do not receive the parentheses as part of their attributes TokenStream. Also the proc_macro_non_items feature is necessary to use async_block.
This commit starts to lay some groundwork for the stabilization of custom
attribute invocations and general procedural macros. It applies a number of
changes discussed on internals as well as a recent issue, namely:
The path used to specify a custom attribute must be of length one and cannot
be a global path. This'll help future-proof us against any ambiguities and
give us more time to settle the precise syntax. In the meantime though a bare
identifier can be used and imported to invoke a custom attribute macro. A new
feature gate,
proc_macro_path_invoc
, was added to gate multi-segment pathsand absolute paths.
The set of items which can be annotated by a custom procedural attribute has
been restricted. Statements, expressions, and modules are disallowed behind
two new feature gates:
proc_macro_expr
andproc_macro_mod
.The input to procedural macro attributes has been restricted and adjusted.
Today an invocation like
#[foo(bar)]
will receive(bar)
as the input tokenstream, but after this PR it will only receive
bar
(the delimiters wereremoved). Invocations like
#[foo]
are still allowed and will be invoked inthe same way as
#[foo()]
. This is a breaking change for all nightlyusers as the syntax coming in to procedural macros will be tweaked slightly.
Procedural macros (
foo!()
style) can only be expanded to item-like items bydefault. A separate feature gate,
proc_macro_non_items
, is required toexpand to items like expressions, statements, etc.
Closes #50038