Skip to content

Adding an attribute to a macro_exported macro and reexporting it incorrectly triggers the macro_expanded_macro_exports_accessed_by_absolute_paths error #98291

Open
@jakobrs

Description

@jakobrs

I tried this code:

#[rustfmt::skip]    // <- The code compiles if this attribute is removed
#[macro_export]
macro_rules! _a {
    () => {
        "Hello world"
    };
}

pub use _a as a;

fn main() {
    println!(a!());
}

(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
error: cannot determine resolution for the macro `a`
  --> ./b.rs:12:14
   |
12 |     println!(a!());
   |              ^
   |
   = note: import resolution is stuck, try simplifying macro imports

error: macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths
 --> ./b.rs:9:9
  |
9 | pub use _a as a;
  |         ^^^^^^^
  |
  = note: `#[deny(macro_expanded_macro_exports_accessed_by_absolute_paths)]` on by default
  = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
  = note: for more information, see issue #52234 <https://github.com/rust-lang/rust/issues/52234>
note: the macro is defined here
 --> ./b.rs:3:1
  |
3 | / macro_rules! _a {
4 | |     () => {
5 | |         "Hello world"
6 | |     };
7 | | }
  | |_^

error: macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths
  --> ./b.rs:12:14
   |
12 |     println!(a!());
   |              ^
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #52234 <https://github.com/rust-lang/rust/issues/52234>
note: the macro is defined here
  --> ./b.rs:3:1
   |
3  | / macro_rules! _a {
4  | |     () => {
5  | |         "Hello world"
6  | |     };
7  | | }
   | |_^

error: aborting due to 3 previous errors

Meta

This happens with Rust 1.60, 1.61 and nightly (bb8c2f4 2022-06-19)
rustc --version --verbose:

# Nightly

rustc 1.63.0-nightly (bb8c2f411 2022-06-19)
binary: rustc
commit-hash: bb8c2f41174caceec00c28bc6c5c20ae9f9a175c
commit-date: 2022-06-19
host: x86_64-unknown-linux-gnu
release: 1.63.0-nightly
LLVM version: 14.0.5

# Stable

rustc 1.61.0 (fe5b13d68 2022-05-18)
binary: rustc
commit-hash: fe5b13d681f25ee6474be29d748c65adcd91f69e
commit-date: 2022-05-18
host: x86_64-unknown-linux-gnu
release: 1.61.0
LLVM version: 14.0.0

Activity

added
A-resolveArea: Name/path resolution done by `rustc_resolve` specifically
A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)
on Jan 26, 2024
fmease

fmease commented on Jan 26, 2024

@fmease
Member

Triage: No longer triggers macro_expanded_macro_exports_accessed_by_absolute_paths.
Current output:

error: cannot determine resolution for the macro `a`
  --> src/main.rs:12:14
   |
12 |     println!(a!());
   |              ^
   |
   = note: import resolution is stuck, try simplifying macro imports
added
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
A-attributesArea: Attributes (`#[…]`, `#![…]`)
on Feb 17, 2024
fmease

fmease commented on Feb 17, 2024

@fmease
Member

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);
}
error: macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths
 --> src/main.rs:9:13
  |
9 |     let t = crate::test_macro!(());
  |             ^^^^^^^^^^^^^^^^^
  |
  = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
  = note: for more information, see issue #52234 <https://github.com/rust-lang/rust/issues/52234>
note: the macro is defined here
 --> src/main.rs:3:1
  |
3 | / macro_rules! test_macro {
4 | |     (()) => { Some(()) };
5 | |     (non) => { None };
6 | | }
  | |_^
  = note: `#[deny(macro_expanded_macro_exports_accessed_by_absolute_paths)]` on by default

fmease

fmease commented on Feb 17, 2024

@fmease
Member

@bvanjoi, perhaps you're interested in looking into the root cause for this. Pinging you since I know that you love to work on A-resolve issues :)

bvanjoi

bvanjoi commented on Feb 17, 2024

@bvanjoi
Contributor

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:

rustc 1.78.0-nightly (ee9c7c940 2024-02-14)
binary: rustc
commit-hash: ee9c7c940c07d8b67c9a6b2ec930db70dcd23a46
commit-date: 2024-02-14
host: aarch64-apple-darwin
release: 1.78.0-nightly
LLVM version: 18.1.0
Backtrace

thread 'rustc' panicked at compiler/rustc_ast_lowering/src/expr.rs:326:77:
called `Option::unwrap()` on a `None` value
stack backtrace:
   0:        0x103a6438c - std::backtrace::Backtrace::create::h82b61cff75ea3f53
   1:        0x10ce07b08 - std[e09757a2c7ce6988]::panicking::update_hook::<alloc[3a60118b2745d164]::boxed::Box<rustc_driver_impl[dca98f68974adbed]::install_ice_hook::{closure#0}>>::{closure#0}
   2:        0x103a7d134 - std::panicking::rust_panic_with_hook::h5f2e6b6c2894b129
   3:        0x103a7cacc - std::panicking::begin_panic_handler::{{closure}}::hd2a8737cdf27ffdd
   4:        0x103a7a430 - std::sys_common::backtrace::__rust_end_short_backtrace::h750d9d4404a9f361
   5:        0x103a7c870 - _rust_begin_unwind
   6:        0x103ad7c24 - core::panicking::panic_fmt::h0e0e4617759d3b1f
   7:        0x103ad7cac - core::panicking::panic::h32049462625288e3
   8:        0x103ad7bd4 - core::option::unwrap_failed::hf79b7e70b841468a
   9:        0x10c621ff8 - <rustc_ast_lowering[4995b37500c4f80b]::LoweringContext>::lower_expr_mut::{closure#0}
  10:        0x10c621974 - <rustc_ast_lowering[4995b37500c4f80b]::LoweringContext>::lower_exprs
  11:        0x10c6221dc - <rustc_ast_lowering[4995b37500c4f80b]::LoweringContext>::lower_expr_mut::{closure#0}
  12:        0x10c61f74c - <rustc_ast_lowering[4995b37500c4f80b]::LoweringContext>::lower_stmts
  13:        0x10c61f50c - <rustc_ast_lowering[4995b37500c4f80b]::LoweringContext>::lower_block
  14:        0x10c622708 - <rustc_ast_lowering[4995b37500c4f80b]::LoweringContext>::lower_expr_mut::{closure#0}
  15:        0x10c61f74c - <rustc_ast_lowering[4995b37500c4f80b]::LoweringContext>::lower_stmts
  16:        0x10c644918 - <rustc_ast_lowering[4995b37500c4f80b]::LoweringContext>::lower_block_expr
  17:        0x10c636438 - <rustc_ast_lowering[4995b37500c4f80b]::LoweringContext>::lower_maybe_coroutine_body
  18:        0x10c62e230 - <rustc_ast_lowering[4995b37500c4f80b]::LoweringContext>::lower_item_kind
  19:        0x10c648204 - <rustc_ast_lowering[4995b37500c4f80b]::LoweringContext>::with_hir_id_owner::<<rustc_ast_lowering[4995b37500c4f80b]::item::ItemLowerer>::with_lctx<<rustc_ast_lowering[4995b37500c4f80b]::item::ItemLowerer>::lower_item::{closure#0}>::{closure#0}>
  20:        0x10c692b78 - <rustc_ast_lowering[4995b37500c4f80b]::item::ItemLowerer>::lower_node
  21:        0x10c63df44 - rustc_ast_lowering[4995b37500c4f80b]::lower_to_hir
  22:        0x10e01c53c - rustc_query_impl[3b9de3a70d57ed7]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[3b9de3a70d57ed7]::query_impl::hir_crate::dynamic_query::{closure#2}::{closure#0}, rustc_middle[6b51fbc1467208f7]::query::erase::Erased<[u8; 8usize]>>
  23:        0x10e0906b0 - <rustc_query_impl[3b9de3a70d57ed7]::query_impl::hir_crate::dynamic_query::{closure#2} as core[8f94067186277a42]::ops::function::FnOnce<(rustc_middle[6b51fbc1467208f7]::ty::context::TyCtxt, ())>>::call_once
  24:        0x10df4fc74 - rustc_query_system[8710640997ca4c58]::query::plumbing::try_execute_query::<rustc_query_impl[3b9de3a70d57ed7]::DynamicConfig<rustc_query_system[8710640997ca4c58]::query::caches::SingleCache<rustc_middle[6b51fbc1467208f7]::query::erase::Erased<[u8; 8usize]>>, false, false, false>, rustc_query_impl[3b9de3a70d57ed7]::plumbing::QueryCtxt, true>
  25:        0x10df29a84 - rustc_query_system[8710640997ca4c58]::query::plumbing::force_query::<rustc_query_impl[3b9de3a70d57ed7]::DynamicConfig<rustc_query_system[8710640997ca4c58]::query::caches::SingleCache<rustc_middle[6b51fbc1467208f7]::query::erase::Erased<[u8; 8usize]>>, false, false, false>, rustc_query_impl[3b9de3a70d57ed7]::plumbing::QueryCtxt>
  26:        0x10dffeb4c - <rustc_query_impl[3b9de3a70d57ed7]::plumbing::query_callback<rustc_query_impl[3b9de3a70d57ed7]::query_impl::hir_crate::QueryType>::{closure#0} as core[8f94067186277a42]::ops::function::FnOnce<(rustc_middle[6b51fbc1467208f7]::ty::context::TyCtxt, rustc_query_system[8710640997ca4c58]::dep_graph::dep_node::DepNode)>>::call_once
  27:        0x10e0f0f38 - <rustc_query_system[8710640997ca4c58]::dep_graph::graph::DepGraphData<rustc_middle[6b51fbc1467208f7]::dep_graph::DepsType>>::try_mark_previous_green::<rustc_query_impl[3b9de3a70d57ed7]::plumbing::QueryCtxt>
  28:        0x10e0f0f80 - <rustc_query_system[8710640997ca4c58]::dep_graph::graph::DepGraphData<rustc_middle[6b51fbc1467208f7]::dep_graph::DepsType>>::try_mark_previous_green::<rustc_query_impl[3b9de3a70d57ed7]::plumbing::QueryCtxt>
  29:        0x10e0f0d00 - <rustc_query_system[8710640997ca4c58]::dep_graph::graph::DepGraphData<rustc_middle[6b51fbc1467208f7]::dep_graph::DepsType>>::try_mark_green::<rustc_query_impl[3b9de3a70d57ed7]::plumbing::QueryCtxt>
  30:        0x10df2be70 - rustc_query_system[8710640997ca4c58]::query::plumbing::ensure_must_run::<rustc_query_impl[3b9de3a70d57ed7]::DynamicConfig<rustc_query_system[8710640997ca4c58]::query::caches::SingleCache<rustc_middle[6b51fbc1467208f7]::query::erase::Erased<[u8; 12usize]>>, false, false, false>, rustc_query_impl[3b9de3a70d57ed7]::plumbing::QueryCtxt>
  31:        0x10e0b15ec - rustc_query_impl[3b9de3a70d57ed7]::query_impl::entry_fn::get_query_incr::__rust_end_short_backtrace
  32:        0x10d56a250 - <rustc_session[34d2f7c8b2ca9bde]::session::Session>::time::<(), rustc_interface[1589e896c9a48ab2]::passes::analysis::{closure#0}::{closure#1}::{closure#0}::{closure#6}::{closure#0}>
  33:        0x10d540870 - std[e09757a2c7ce6988]::panicking::try::<(), core[8f94067186277a42]::panic::unwind_safe::AssertUnwindSafe<rustc_interface[1589e896c9a48ab2]::passes::analysis::{closure#0}::{closure#0}::{closure#0}>>
  34:        0x10d501a4c - <rustc_data_structures[5a29570388e79f5e]::sync::parallel::ParallelGuard>::run::<(), rustc_interface[1589e896c9a48ab2]::passes::analysis::{closure#0}::{closure#0}::{closure#0}>
  35:        0x10d56a9dc - <rustc_session[34d2f7c8b2ca9bde]::session::Session>::time::<(), rustc_interface[1589e896c9a48ab2]::passes::analysis::{closure#0}>
  36:        0x10d4eb618 - rustc_interface[1589e896c9a48ab2]::passes::analysis
  37:        0x10e01c250 - rustc_query_impl[3b9de3a70d57ed7]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[3b9de3a70d57ed7]::query_impl::analysis::dynamic_query::{closure#2}::{closure#0}, rustc_middle[6b51fbc1467208f7]::query::erase::Erased<[u8; 1usize]>>
  38:        0x10e1af0b4 - <rustc_query_impl[3b9de3a70d57ed7]::query_impl::analysis::dynamic_query::{closure#2} as core[8f94067186277a42]::ops::function::FnOnce<(rustc_middle[6b51fbc1467208f7]::ty::context::TyCtxt, ())>>::call_once
  39:        0x10df4c7a8 - rustc_query_system[8710640997ca4c58]::query::plumbing::try_execute_query::<rustc_query_impl[3b9de3a70d57ed7]::DynamicConfig<rustc_query_system[8710640997ca4c58]::query::caches::SingleCache<rustc_middle[6b51fbc1467208f7]::query::erase::Erased<[u8; 1usize]>>, false, false, false>, rustc_query_impl[3b9de3a70d57ed7]::plumbing::QueryCtxt, true>
  40:        0x10e0ae930 - rustc_query_impl[3b9de3a70d57ed7]::query_impl::analysis::get_query_incr::__rust_end_short_backtrace
  41:        0x10cde7828 - <rustc_middle[6b51fbc1467208f7]::ty::context::GlobalCtxt>::enter::<rustc_driver_impl[dca98f68974adbed]::run_compiler::{closure#0}::{closure#0}::{closure#3}, core[8f94067186277a42]::result::Result<(), rustc_span[1bac0d14ce0e9ad9]::ErrorGuaranteed>>
  42:        0x10cdaa760 - <rustc_interface[1589e896c9a48ab2]::interface::Compiler>::enter::<rustc_driver_impl[dca98f68974adbed]::run_compiler::{closure#0}::{closure#0}, core[8f94067186277a42]::result::Result<core[8f94067186277a42]::option::Option<rustc_interface[1589e896c9a48ab2]::queries::Linker>, rustc_span[1bac0d14ce0e9ad9]::ErrorGuaranteed>>
  43:        0x10cde53f4 - rustc_span[1bac0d14ce0e9ad9]::set_source_map::<core[8f94067186277a42]::result::Result<(), rustc_span[1bac0d14ce0e9ad9]::ErrorGuaranteed>, rustc_interface[1589e896c9a48ab2]::interface::run_compiler<core[8f94067186277a42]::result::Result<(), rustc_span[1bac0d14ce0e9ad9]::ErrorGuaranteed>, rustc_driver_impl[dca98f68974adbed]::run_compiler::{closure#0}>::{closure#0}::{closure#0}>
  44:        0x10cde6a70 - rustc_span[1bac0d14ce0e9ad9]::create_session_globals_then::<core[8f94067186277a42]::result::Result<(), rustc_span[1bac0d14ce0e9ad9]::ErrorGuaranteed>, rustc_interface[1589e896c9a48ab2]::util::run_in_thread_pool_with_globals<rustc_interface[1589e896c9a48ab2]::interface::run_compiler<core[8f94067186277a42]::result::Result<(), rustc_span[1bac0d14ce0e9ad9]::ErrorGuaranteed>, rustc_driver_impl[dca98f68974adbed]::run_compiler::{closure#0}>::{closure#0}, core[8f94067186277a42]::result::Result<(), rustc_span[1bac0d14ce0e9ad9]::ErrorGuaranteed>>::{closure#0}>
  45:        0x10ce057c4 - std[e09757a2c7ce6988]::sys_common::backtrace::__rust_begin_short_backtrace::<rustc_interface[1589e896c9a48ab2]::util::run_in_thread_with_globals<rustc_interface[1589e896c9a48ab2]::util::run_in_thread_pool_with_globals<rustc_interface[1589e896c9a48ab2]::interface::run_compiler<core[8f94067186277a42]::result::Result<(), rustc_span[1bac0d14ce0e9ad9]::ErrorGuaranteed>, rustc_driver_impl[dca98f68974adbed]::run_compiler::{closure#0}>::{closure#0}, core[8f94067186277a42]::result::Result<(), rustc_span[1bac0d14ce0e9ad9]::ErrorGuaranteed>>::{closure#0}, core[8f94067186277a42]::result::Result<(), rustc_span[1bac0d14ce0e9ad9]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[8f94067186277a42]::result::Result<(), rustc_span[1bac0d14ce0e9ad9]::ErrorGuaranteed>>
  46:        0x10cdfbb78 - <<std[e09757a2c7ce6988]::thread::Builder>::spawn_unchecked_<rustc_interface[1589e896c9a48ab2]::util::run_in_thread_with_globals<rustc_interface[1589e896c9a48ab2]::util::run_in_thread_pool_with_globals<rustc_interface[1589e896c9a48ab2]::interface::run_compiler<core[8f94067186277a42]::result::Result<(), rustc_span[1bac0d14ce0e9ad9]::ErrorGuaranteed>, rustc_driver_impl[dca98f68974adbed]::run_compiler::{closure#0}>::{closure#0}, core[8f94067186277a42]::result::Result<(), rustc_span[1bac0d14ce0e9ad9]::ErrorGuaranteed>>::{closure#0}, core[8f94067186277a42]::result::Result<(), rustc_span[1bac0d14ce0e9ad9]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[8f94067186277a42]::result::Result<(), rustc_span[1bac0d14ce0e9ad9]::ErrorGuaranteed>>::{closure#1} as core[8f94067186277a42]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  47:        0x103a8500c - std::sys::pal::unix::thread::Thread::new::thread_start::hc285c3138ab3bdc5
  48:        0x1845fe034 - __pthread_joiner_wake


rustc version: 1.78.0-nightly (ee9c7c940 2024-02-14)
platform: aarch64-apple-darwin

query stack during panic:
#0 [hir_crate] getting the crate HIR
#1 [analysis] running analysis passes on this crate
end of query stack

I plan to delve into this in the near future. @rustbot claim

edit: no ice in rustc 1.78.0-nightly (bccb9bbb4 2024-02-16)

bvanjoi

bvanjoi commented on Feb 26, 2024

@bvanjoi
Contributor

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.

bvanjoi

bvanjoi commented on Feb 26, 2024

@bvanjoi
Contributor

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.

added 3 commits that reference this issue on Mar 5, 2024

Auto merge of rust-lang#121589 - bvanjoi:fix-98291, r=<try>

8b0b849

Auto merge of rust-lang#121589 - bvanjoi:fix-98291, r=<try>

0af3b72

Auto merge of rust-lang#121589 - bvanjoi:fix-98291, r=petrochenkov

184c5ab
nyurik

nyurik commented on Feb 21, 2025

@nyurik
Contributor

I ran into this issue when I tried to add a new #[clippy::format_args] to a large project's logging macros. Reproducible with this on Rust v1.85. I have no idea how to even approach it, let alone the reason for this.

#[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!");
    }
}
error: macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths
  --> src/main.rs:16:9
   |
16 |     use crate::my_log;
   |         ^^^^^^^^^^^^^
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #52234 <https://github.com/rust-lang/rust/issues/52234>
note: the macro is defined here
  --> src/main.rs:3:1
   |
3  | / macro_rules! my_log {
4  | |     ($($t:tt)*) => ($crate::my_log_impl(format_args!($($t)*)))
5  | | }
   | |_^
   = note: `#[deny(macro_expanded_macro_exports_accessed_by_absolute_paths)]` on by default

nyurik

nyurik commented on Feb 23, 2025

@nyurik
Contributor

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 log crate worked ok.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-attributesArea: Attributes (`#[…]`, `#![…]`)A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)A-resolveArea: Name/path resolution done by `rustc_resolve` specificallyC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @nyurik@ChrisDenton@jakobrs@fmease@bvanjoi

      Issue actions

        Adding an attribute to a `macro_export`ed macro and reexporting it incorrectly triggers the macro_expanded_macro_exports_accessed_by_absolute_paths error · Issue #98291 · rust-lang/rust