-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Tracking issue for custom inner attributes #54726
Comments
Summary:
|
(I'll fill in details about why this is unstable soon.) |
So, the primary open question about inner attributes is what scope they are resolved in. For example: use xxx::attr;
mod m {
#![attr]
use yyy::attr;
} Does Right now, However, if something is inside a module (or block, etc) it's normally reasonable to expect that it's resolved from inside of that module as well. With attributes such resolution from the inside causes problems though. First of all, there's no "inside" before we expand all the macro attributes.
is just a token stream, even if it looks like module and items, it effectively doesn't exist in the module structure of the crate yet.
Possible solutions to this problem:
|
This variant is the way to go right now, I think. |
…phansch Add several run rustfix annotations Adds `run-rustfix` to 18 of the tests from the tracking issue #3630. Each test has its own commit, to make reviewing easier (hopefully this is easier to review than 18 separate PRs). ## Changes - `cfg_attr_rustfmt`: Custom inner attributes are unstable. Let's disable the lint for inner attributes until [#54726](rust-lang/rust#54726) stabilizes - `collapsible_if`: unrelated cyclomatic_complexity warning that can be ignored - `duration_subsec`: Simply needed `#![allow(dead_code)]` - `excessive_precision`: Fixed by `#!allow(dead_code,unused_variables)` - `explicit_write`: Fixed by `#![allow(unused_imports)]` - `inconsistent_digit_grouping`: Avoid triggering `clippy::excessive_precision` lint - `infallible_destructuring_match`: Fixed by `#![allow(dead_code, unreachable_code, unused_variables)]` - `into_iter_on_ref`: Triggered unrelated `clippy::useless_vec` lint - `large_digit_groups`: Avoid triggering `clippy::excessive_precision` lint - `map_clone`: Fixed by `#![allow(clippy::iter_cloned_collect)]` - `mem_replace`: Suggestion causes import to be unused, fixed by `#![allow(unused_imports)]` - `precedence`: Allow some unrelated lints, and change out-of-range `0b1111_1111i8` literal - `redundant_field_names`: Allow dead code, and remove stabilized feature toggles - `replace_consts`: Fixed by `#![allow(unused_variables)]` - `starts_ends_with`: Fixed by `#![allow(unused_must_use)]` - `types`: Fixed by `#![allow(dead_code, unused_variables)]` - `unit_arg`: Fixed by `#[allow(unused_must_use)]` - `unnecessary_fold`: Fixed by adding type annotations and adding `#![allow(dead_code)]`
The caveat is that adding |
My use case for this feature would be to have a custom crate level attribute in a #![custom_attr_here]
fn main() {
// [...]
} There is no outer scope here to resolve that custom attribute. |
@mehcode
For locally defined/imported attributes that's probably the hardest case though, it certainly requires eager expansion. |
Sorry if I'm missing something important, but it seems to me that current behaviour of custom inner attributes is rather inconsistent. For example, if i have file named #![my_macro]
mod bar {
#![my_macro]
fn some_fn () {
}
} then first invocation of #![my_macro] receives token stream equivalent to mod bar {
fn some_fn() { }
} So custom inner attribute receives no module content if that module is placed in it's own file, but what's even stranger is that this is not always the case. If i add Is there any chance to make this behavior more consistent? Current behavior could result in unwanted suprises when somebody decides for example to do refactoring and split modules to dedicated files. |
I tried adding a custom attribute using
using lib.rs #![feature(custom_inner_attributes, proc_macro_hygiene)]
#![my_attr] and in the proc_macro crate #[proc_macro_attribute]
pub fn my_attr(_args: TokenStream, input: TokenStream) -> TokenStream {
let module = parse_macro_input!(input as syn::ItemMod);
let content = module.content.unwrap().1; // workaround for mod having no name
proc_macro::TokenStream::from(quote! { #(#content)* })
} The error is coming from the |
@nhynes The recommendation is to make a module and apply the attribute to it instead. |
This broke stdsimd, which uses
|
@gnzlbg |
Weird, this started erroring this week. |
@gnzlbg Previously |
Fix 59191 - ICE when macro replaces crate root with non-module item Hi, This should fix rust-lang#59191! My friend and I are working on learning the rustc codebase through contributions, so please feel free to mention anything amiss or that could be done better. The code adds an explicit case for when a macro applied to the crate root (via an inner attribute) replaces it with something nonsensical, like a function. The crate root must be a module, and the error message reflects this. --- I should note that there are a few other weird edge cases here, like if they do output a module, it succeeds but uses that module's name as a prefix for all names in the crate. I'm assuming that's an issue for stabilizing rust-lang#54726, though.
I'd like this so I can expand a whole bunch of lint rules org-wide from one library attribute line. That'd be quite nicer than the current mess it gives us. |
expand: Turn `ast::Crate` into a first class expansion target And stop creating a fake `mod` item for the crate root when expanding a crate, thus addressing FIXMEs left in rust-lang#82238, and making a step towards a proper support for crate-level macro attributes (cc rust-lang#54726). I haven't added token collection support for the whole crate in this PR, maybe later. r? `@Aaron1011`
I don't know whether this was already implicitly finalized, but I haven't seen two other possibilities suggested;
|
Is there any way to work around this limitation at the crate root? |
My use case for this is I am the author of a crate that allows for annotating a module with a cryptographic signature indicating that it has been audited (based on a hash of the underlying AST nodes of the module). Ideally we would only allow using this for top-level whole-file inner attributes, as for these you can safely assume that no unaudited items are being sideloaded into the module. Right now we have to do complex filtering of the module to ensure that every item referenced in the module is part of the audited footprint. With top-of-file inner attributes, this filtering is a lot simpler. So would love to see this stabilized, with the ability to tell whether a particular attribute is "top-level" in a file or not. That would help us out a lot. |
Not sure if this should be a separate issue or not, or where it should live (let me know and I can create it elsewhere), but there seems to be a weird quirk with Repro case: https://github.com/Qix-/repro-no_std-custom-inner-attr Results in this error message:
|
Yeah this is a rather sizable wart when you want to use an attribute macro in the root crate ( lib.rs ) because there is no way to decorate the crate itself outside of it. :/ |
Would it be possible to remove the feature gate if the inner attribute is at the crate root? It seems like the ambiguity doesn't actually apply there, and that's the key spot where there's no alternative / workaround. |
i want to make a crate that uses this feature at the crate root and, honestly, i don't really want my users to have to enable this feature just to use my crate. it seems like there's been no recent discussion on the issue so I'm going to go see if i can remove the feature gate for my users' convenience. |
would love to see this feature come through, seems super useful to custom have inner attributes! |
Added in #54093 inner attributes are not allowed to be procedural macros right now, and this issue is tracking that feature of procedural macros!
Assistance in filling in this issue would be greatly appreciated!
UPDATE: #54726 (comment) below contains the detailed description.
The text was updated successfully, but these errors were encountered: