-
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
Bad suggestion for macro_rules macros generated from a proc-macro #132906
Comments
For the record, the macro_rules that is generated will be spanned using the edition of the callsite, so it'll be edition 2024 even if the proc macro is edition 2021. |
I'm wondering if the switch of edition is happening here, where it uses the session edition to compile the macro, instead of the edition where the macro was defined. |
Another test case, which is a bit different in that it's testing in which edition the macro fragment specifiers are evaluated: // In the proc macro crate:
//@ edition: 2021
extern crate proc_macro;
use proc_macro::TokenStream;
#[proc_macro_attribute]
pub fn pm(_attr: TokenStream, _item: TokenStream) -> TokenStream {
r#"macro_rules! edition {
($_:expr) => {
println!("Rust 2024")
};
(const {}) => {
println!("Rust 2021")
};
}
"#
.parse()
.unwrap()
}
// In another crate:
//@ edition: 2024
use macros_proc::pm;
#[macros_proc::pm]
struct S;
fn main() {
edition!(const {});
} This prints "Rust 2021". |
Here's another test case: // In the proc macro crate:
//@ edition: 2021
extern crate proc_macro;
use proc_macro::TokenStream;
#[proc_macro_attribute]
pub fn pm(_attr: TokenStream, _item: TokenStream) -> TokenStream {
r#"macro_rules! edition {
($d:tt) => { macro_rules! edition_inner {
($d_:expr) => {
println!("Rust 2024")
};
(const {}) => {
println!("Rust 2021")
};
}};
}
"#
.parse()
.unwrap()
}
// In another crate:
//@ edition: 2024
use macros_proc::pm;
#[macros_proc::pm]
struct S;
fn main() {
edition!($);
edition_inner!(const {});
} This prints "Rust 2024". |
I posted a partial fix in #133274. That fixes the problem that a 2024 crate would error when using a proc-macro from an older edition that emits a macro_rules macro. I still don't know how to fix the lint firing in 2021 in that same situation. Somehow there should be a way for the lint to recognize that the place it is adding a suggestion to is not correct, and that it doesn't need to fire at all... |
…=<try> Use edition of `macro_rules` when compiling the macro This changes the edition assigned to a macro_rules macro when it is compiled to use the edition of where the macro came from instead of the local crate's edition. This fixes a problem when a macro_rules macro is created by a proc-macro. Previously that macro would be tagged with the local edition, which would cause problems with using the correct edition behavior inside the macro. For example, the check for unsafe attributes would cause errors in 2024 when using proc-macros from older editions. This is partially related to rust-lang#132906. Unfortunately this is only a half fix for that issue. It fixes the error that happens in 2024, but does not fix the lint firing in 2021. I'm still trying to think of some way to fix that, but I'm running low on ideas.
In a proc-macro that generates a macro_rules macro that triggers lints like
unsafe_op_in_unsafe_fn
, orunsafe_attr_outside_unsafe
, the suggestion ends up suggesting that theunsafe
should go around the attribute, which is invalid syntax.Gives a suggestion that ends up being:
which is invalid syntax.
Seen with the
vtable
crate.This is a bit of curious case, as I would have expected the tokens of the macro_rules definition to be 2021 edition, and that the tokens it in turns generates also be 2021. Offhand I don't know how macro_rules determine which edition the tokens it emits should be (I'm guessing it is using the edition of the local crate, instead of the edition of the generated macro_rules definition).
Meta
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: