rust-lang/rust

Mod item in procedural macro output looks for the wrong source file

Closed this issue · 4 comments

I have this crate layout:

  • Cargo.toml
  • src/
    • main.rs
    • parent/
      • child.rs

where child.rs is an empty file and main.rs is:

mod parent {
    mod child;
}

fn main() {}

This compiles successfully and we end up with a module at crate::parent::child backed by the file src/parent/child.rs.

But if mod child; goes anywhere near a proc macro, it no longer works.

mod parent {
    repro::noop! { mod child; }
}

fn main() {}

where noop! is this macro:

#[proc_macro]
pub fn noop(input: TokenStream) -> TokenStream {
    input
}

The error is:

error[E0583]: file not found for module `child`
 --> src/main.rs:2:5
  |
2 |     repro::noop! { mod child; }
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = help: name the file either child.rs or child/mod.rs inside the directory "src"

so it is looking for a file corresponding to mod child as though the mod child were not contained inside of mod parent. I hit this while working on https://github.com/dtolnay/automod.

The same problem does not occur if noop! is defined as a macro_rules macro.

Repro script

#!/bin/bash

cargo new repro

echo >>repro/Cargo.toml '
[lib]
proc-macro = true
'

echo >repro/src/lib.rs '
extern crate proc_macro;
use proc_macro::TokenStream;

#[proc_macro]
pub fn noop(input: TokenStream) -> TokenStream {
    input
}
'

echo >repro/src/main.rs '
mod parent {
    repro::noop! { mod child; }
}

fn main() {}
'

mkdir repro/src/parent
touch repro/src/parent/child.rs

cargo check --manifest-path repro/Cargo.toml

Mentioning @petrochenkov who may know what is going wrong or whether there is a simple rustc fix.

I never audited the module search code and don't know how it fits into the larger macro story.
Even without macros it's pretty inconsistent, so I'd expect issues in macros as well.
I'll investigate.

Still the same behavior as of rustc 1.40.0-nightly (702b45e 2019-10-01).

It's still in my queue, just not with a high enough priority :(

This was fixed by #69838, I'll add a test.