Skip to content

really bad error messages for trying to use a macro from a module #57966

Open
@durka

Description

@durka

If you read up on new-style macro imports in the edition guide and miss the tiny note that it doesn't work for macros in modules in your own crate (why not?!), you might try this:

mod has_a_macro {
    macro_rules! a_macro { () => {} }
}

use crate::has_a_macro::a_macro;

fn main() {
    a_macro!();
}

BIG MISTAKE.

error[E0432]: unresolved import `crate::has_a_macro::a_macro`
 --> src/main.rs:6:5
  |
6 | use crate::has_a_macro::a_macro;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `a_macro` in `has_a_macro`

error: cannot determine resolution for the macro `a_macro`
 --> src/main.rs:8:5
  |
8 |     a_macro!();
  |     ^^^^^^^
  |
  = note: import resolution is stuck, try simplifying macro imports

error: aborting due to 2 previous errors

OK, two errors here, neither of which are helpful.

The first one simply says the macro doesn't exist when it obviously does, this is just the compiler gaslighting the user. Next!

The second one is fairly hilarious (this is already the simplest situation possible) and unactionable.

Let's see... I know that in the past you used to put #[macro_use] above the mod declaration to do this. Adding that nets a different second error:

error[E0659]: `a_macro` is ambiguous (`macro_rules` vs non-`macro_rules` from other module)
 --> src/main.rs:9:5
  |
9 |     a_macro!();
  |     ^^^^^^^ ambiguous name
  |
note: `a_macro` could refer to the macro defined here
 --> src/main.rs:3:5
  |
3 |     macro_rules! a_macro { () => {} }
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `a_macro` could also refer to the unresolved item imported here
 --> src/main.rs:6:5
  |
6 | use crate::has_a_macro::a_macro;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  = help: use `crate::a_macro` to refer to this unresolved item unambiguously

This is... really confusing. I can see that the compiler knows exactly which macro I want to call, but it refuses to do it, and for some reason it says it's ambiguous with the statement trying to import it. The `macro_rules` vs non-`macro_rules` word salad doesn't help matters.

Also, the suggestion doesn't work, you just get the original import resolution is stuck error back.

So, the eventual solution is to remove the use statement, leaving only #[macro_use], but this isn't discoverable from the mess of errors. Can we take off the compiler-colored glasses and make better diagnostics for this situation? I can't imagine I'm the only person who tried this.

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsA-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)A-resolveArea: Name/path resolution done by `rustc_resolve` specificallyC-enhancementCategory: An issue proposing an enhancement or a PR with one.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

Issue actions