Skip to content
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

using inner tool attributes in crate root induces compiler error on intra-crate macro use #74087

Open
bcantrill opened this issue Jul 6, 2020 · 6 comments
Labels
A-attributes Area: Attributes (`#[…]`, `#![…]`) A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) A-resolve Area: Name/path resolution done by `rustc_resolve` specifically C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@bcantrill
Copy link

Take a crate that has the following foo.rs, that contains a macro, foomacro()!:

#[macro_export]
macro_rules! foomacro {
    ($f:expr) => ({
        println!("foomacro: {}", $f);
    });
}

This macro is used in bar.rs:

use crate::foomacro;

pub fn bar() {
    foomacro!("bar");
}

Finally, here is the root of the crate and main.rs:

#![feature(custom_inner_attributes)]

// Setting any inner tool attribute here causes a compiler error on bar's use of
// foomacro!():
//
//   error: macro-expanded `macro_export` macros from the current crate cannot
//   be referred to by absolute paths
//
// To see this, uncomment either of the following lines:
//
// #![clippy::cyclomatic_complexity = "100"]
// #![rustfmt::skip]

mod foo;
mod bar;

fn main() {
    foomacro!("foo");
    bar::bar();
}

As the comment there indicates, as written, this compiles and runs as expected:

$ cargo run
   Compiling modmac v0.1.0 (/home/bmc/modmac)
    Finished dev [unoptimized + debuginfo] target(s) in 0.18s
     Running `target/debug/modmac`
foomacro: foo
foomacro: bar

If, however, either of the inner tool attributes is uncommented, the code fails on compiling bar.rs, complaining about its use of foomacro()!

$ cargo run
   Compiling modmac v0.1.0 (/home/bmc/modmac)
error: macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths
 --> src/bar.rs:2:5
  |
2 | use crate::foomacro;
  |     ^^^^^^^^^^^^^^^
  |
  = 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
 --> src/foo.rs:2:1
  |
2 | / macro_rules! foomacro {
3 | |     ($f:expr) => ({
4 | |         println!("foomacro: {}", $f);
5 | |     });
6 | | }
  | |_^

error: aborting due to previous error

error: could not compile `modmac`.

This behavior seems surprising, especially because tool attributes are generally thought to only be relevant to the specified tool:

When a tool is not in use, the tool's attributes are accepted without a warning. When the tool is in use, the tool is responsible for processing and interpretation of its attributes.

Thanks in advance for any consideration of this issue -- and apologies if this is an elaborate form of pilot error!

@bcantrill bcantrill added the C-bug Category: This is a bug. label Jul 6, 2020
@jonas-schievink jonas-schievink added A-attributes Area: Attributes (`#[…]`, `#![…]`) A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) A-resolve Area: Name/path resolution done by `rustc_resolve` specifically T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jul 6, 2020
@Kestrer
Copy link
Contributor

Kestrer commented Oct 28, 2020

I created a smaller example that reproduces the bug:

#[macro_export]
#[rustfmt::skip]
macro_rules! m {
    () => {};
}

#[macro_export]
macro_rules! other {
    () => {
        $crate::m!();
    }
}

other!();

@jonas-schievink
Copy link
Contributor

@petrochenkov might know what's going on there

@petrochenkov
Copy link
Contributor

custom_inner_attributes are happening, #54726 has an explanation of issues with them.
Custom attributes at crate level are a particularly tricky case.

@Kestrer
Copy link
Contributor

Kestrer commented Oct 28, 2020

This problem is actually unrelated to custom inner attributes, my example above reproduced it using only outer attributes.

@petrochenkov
Copy link
Contributor

petrochenkov commented Oct 28, 2020

Ah, I see, then it's #52234 (comment).

#[rustfmt::skip] is considered "potentially a macro" (because we need to resolve it to figure out whether it's a macro invocation or not), and it's enough to mark macro_rules! m { () => {}; } from the example above as "potentially macro-expanded" and trigger the condition.

@PoignardAzur
Copy link
Contributor

I've hit this problem recently and it's nasty.

A minimal example:

// Uncomment the following to trigger a compile error.
//#[rustfmt::skip]
mod my_macro {
    #[macro_export]
    macro_rules! my_macro {
        () => {
            "Hello world"
        };
    }
}

fn main() {
    println!(crate::my_macro!());
}

tamasfe added a commit to rhaiscript/lsp that referenced this issue Jun 30, 2022
I intended to keep it, however it's impossible to apply rustfmt::skip to it, causing diff issues.

related: rust-lang/rust#74087
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-attributes Area: Attributes (`#[…]`, `#![…]`) A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) A-resolve Area: Name/path resolution done by `rustc_resolve` specifically C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants