-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Adding an attribute to a macro_export
ed macro and reexporting it incorrectly triggers the macro_expanded_macro_exports_accessed_by_absolute_paths error
#98291
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
Comments
Triage: No longer triggers
|
Related reproducer from #121219 (different error): #[macro_export]
#[rustfmt::skip]
macro_rules! test_macro {
(()) => { Some(()) };
(non) => { None };
}
fn main() {
let t = crate::test_macro!(());
println!("{:?}", t);
}
|
@bvanjoi, perhaps you're interested in looking into the root cause for this. Pinging you since I know that you love to work on |
It's noteworthy that this case had previously induced an ice: // rustc code.rs --edition=2021
#[rustfmt::skip]
macro_rules! _a {
() => {
"Hello world"
};
}
use _a as a;
fn main() {
println!(a!());
} rustc version:
Backtrace
I plan to delve into this in the near future. @rustbot claim edit: no ice in |
This issue encompasses two problems: firstly // rustc code.rs --edition=2018
macro_rules! wrap {
() => {
macro_rules! _a {
() => {
"Hello world"
};
}
};
}
wrap!();
use _a as a;
fn main() {
format_args!(a!()); // it will throw unresolved error
} And it will resolved by #121589. |
And secondly: // rustc code.rs --edition=2015
macro_rules! wrap {
() => {
#[macro_export]
macro_rules! _a {
() => {
"Hello world"
};
}
};
}
wrap!();
use _a as a;
//^ throw error contains `macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths`
fn main() {
let a = crate::a!();
format_args!("{:#?}", a);
} I will delve into this case at a later point. |
try to resolve under eager expander Fixes rust-lang#98291 I will attempt to clarify the root problem through several examples: Firstly, ```rs // rustc code.rs --edition=2018 macro_rules! wrap { () => { macro_rules! _a { () => { "Hello world" }; } }; } wrap!(); use _a as a; fn main() { format_args!(_a!()); } ``` The above case will compile successfully because `_a` is defined after the `wrap` expaned, ensuring `_a` can be resolved without any issues. And, ```rs // rustc code.rs --edition=2018 macro_rules! wrap { () => { macro_rules! _a { () => { "Hello world" }; } }; } wrap!(); use _a as a; fn main() { format_args!("{}", a!()); } ``` The above example will also compile successfully because the `parse_args` in `expand_format_args_impl` will return a value `MacroInput { fmtstr: Expr::Lit::Str, args: [Expr::MacroCall]}`. Since the graph for `args` will be build lately, `a` will eventually be resolved. However, in the case of: ```rs // rustc code.rs --edition=2018 macro_rules! wrap { () => { macro_rules! _a { () => { "Hello world" }; } }; } wrap!(); use _a as a; fn main() { format_args!(a!()); } ``` The result of `parse_args` is `MacroInput {fmtstr: Expr::Lit::Macro, args: [] }`, we attempt to expand `fmtstr` **eagerly** within `expr_to_spanned_string`. Although we have recorded `(root, _a)` into resolutions, `use _a as a` is an indeterminate import, which will not try to resolve under the conditions of `expander.monotonic = false`. Therefore, I've altered the strategy for resolving indeterminate imports, ensuring it will also resolve during eager expansion. This could be a significant change to the resolution infra. However, I think it's acceptable if the goal of avoiding resolution under eager expansion is to save time. r? `@petrochenkov`
delay expand macro bang when there has indeterminate path Related rust-lang#98291 I will attempt to clarify the root problem through several examples: Firstly, ```rs // rustc code.rs --edition=2018 macro_rules! wrap { () => { macro_rules! _a { () => { "Hello world" }; } }; } wrap!(); use _a as a; fn main() { format_args!(_a!()); } ``` The above case will compile successfully because `_a` is defined after the `wrap` expaned, ensuring `_a` can be resolved without any issues. And, ```rs // rustc code.rs --edition=2018 macro_rules! wrap { () => { macro_rules! _a { () => { "Hello world" }; } }; } wrap!(); use _a as a; fn main() { format_args!("{}", a!()); } ``` The above example will also compile successfully because the `parse_args` in `expand_format_args_impl` will return a value `MacroInput { fmtstr: Expr::Lit::Str, args: [Expr::MacroCall]}`. Since the graph for `args` will be build lately, `a` will eventually be resolved. However, in the case of: ```rs // rustc code.rs --edition=2018 macro_rules! wrap { () => { macro_rules! _a { () => { "Hello world" }; } }; } wrap!(); use _a as a; fn main() { format_args!(a!()); } ``` The result of `parse_args` is `MacroInput {fmtstr: Expr::Lit::Macro, args: [] }`, we attempt to expand `fmtstr` **eagerly** within `expr_to_spanned_string`. Although we have recorded `(root, _a)` into resolutions, `use _a as a` is an indeterminate import, which will not try to resolve under the conditions of `expander.monotonic = false`. Therefore, I've altered the strategy for resolving indeterminate imports, ensuring it will also resolve during eager expansion. This could be a significant change to the resolution infra. However, I think it's acceptable if the goal of avoiding resolution under eager expansion is to save time. r? `@petrochenkov`
delay expand macro bang when there has indeterminate path Related rust-lang#98291 I will attempt to clarify the root problem through several examples: Firstly, ```rs // rustc code.rs --edition=2018 macro_rules! wrap { () => { macro_rules! _a { () => { "Hello world" }; } }; } wrap!(); use _a as a; fn main() { format_args!(_a!()); } ``` The above case will compile successfully because `_a` is defined after the `wrap` expaned, ensuring `_a` can be resolved without any issues. And, ```rs // rustc code.rs --edition=2018 macro_rules! wrap { () => { macro_rules! _a { () => { "Hello world" }; } }; } wrap!(); use _a as a; fn main() { format_args!("{}", a!()); } ``` The above example will also compile successfully because the `parse_args` in `expand_format_args_impl` will return a value `MacroInput { fmtstr: Expr::Lit::Str, args: [Expr::MacroCall]}`. Since the graph for `args` will be build lately, `a` will eventually be resolved. However, in the case of: ```rs // rustc code.rs --edition=2018 macro_rules! wrap { () => { macro_rules! _a { () => { "Hello world" }; } }; } wrap!(); use _a as a; fn main() { format_args!(a!()); } ``` The result of `parse_args` is `MacroInput {fmtstr: Expr::Lit::Macro, args: [] }`, we attempt to expand `fmtstr` **eagerly** within `expr_to_spanned_string`. Although we have recorded `(root, _a)` into resolutions, `use _a as a` is an indeterminate import, which will not try to resolve under the conditions of `expander.monotonic = false`. Therefore, I've altered the strategy for resolving indeterminate imports, ensuring it will also resolve during eager expansion. This could be a significant change to the resolution infra. However, I think it's acceptable if the goal of avoiding resolution under eager expansion is to save time. r? `@petrochenkov`
I ran into this issue when I tried to add a new #[clippy::format_args]
#[macro_export]
macro_rules! my_log {
($($t:tt)*) => ($crate::my_log_impl(format_args!($($t)*)))
}
pub fn my_log_impl(args: core::fmt::Arguments) {
println!("{}", args);
}
fn main() {
sub::run();
}
mod sub {
use crate::my_log;
pub fn run() {
my_log!("Hello, world!");
}
}
|
CC: @bvanjoi and @petrochenkov I saw you had a relevant PR #121589, but it seems the bug is still there. Moreover, it is now more visible because v1.85 introduced an ability for Clippy to lint code when the 3rd party crates include an attribute on a macro. I tried adding the new attribute to both stdlib and 3rd party crates, and only the |
I tried this code:
(https://gist.github.com/jakobrs/8bcaf3448431126005e16ac678f769c5)
I expected to see this happen: The code should compile successfully.
Instead, this happened: The
macro_expanded_macro_exports_accessed_by_absolute_paths
error is triggered.Full error message
Meta
This happens with Rust 1.60, 1.61 and nightly (bb8c2f4 2022-06-19)
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: