rustc: Tweak custom attribute capabilities#50120
Conversation
21ad04d to
de1e1a7
Compare
src/libsyntax/ext/expand.rs
Outdated
There was a problem hiding this comment.
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.
Aha excellent point, tests added and fixed
src/libsyntax/ext/expand.rs
Outdated
There was a problem hiding this comment.
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.
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.
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_exprandproc_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