Skip to content

decl_macro expansion in 2018 context cannot refer to external crates at the root #55668

Closed
@jebrosen

Description

@jebrosen

decl_macros that are invoked in a 2018 edition crate can fail depending on how the macro's paths are defined.

Minimized example:

#![feature(decl_macro)]

macro test {
    () => {
        ::std::vec::Vec::new()
    }
}

fn main() {
    let x: Vec<i32> = test!();
}

In the 2018 edition, this fails to compile:

error[E0433]: failed to resolve. Could not find `std` in `{{root}}`
  --> src/main.rs:5:11
   |
5  |         ::std::vec::Vec::new()
   |           ^^^ Could not find `std` in `{{root}}`
...
10 |     let x: Vec<i32> = test!();
   |                       ------- in this macro invocation

error: aborting due to previous error

The edition at the expansion location is what matters in this case, not the edition in which the macro is defined. Other crates show the same error message, not just std.

The workarounds that I have found so far are to start the path with std (no leading ::), or to add extern crate std; into the macro itself. The former is not a usable option when the decl_macro is generated by a proc_macro, because the crate std could be shadowed by a module named std at the "real" decl_macro definition site.

My bisect of the more complicated example pointed to #54658 -- cc @petrochenkov

cc @SergioBenitez

Metadata

Metadata

Assignees

Labels

A-decl-macros-2-0Area: Declarative macros 2.0 (#39412)A-resolveArea: Name/path resolution done by `rustc_resolve` specifically

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions