Closed marmeladema closed 4 years ago
I managed to reproduce the bug with a regular macro rules:
#![feature(rustc_attrs)]
fn main() {
|| {
#[macro_export] #[rustc_macro_transparency = "opaque"] macro_rules! m { () => {} }
};
}
The problem is more broader that I originally thought but I still don't exactly know how to solve it quite yet.
The issue is due to an AST simplification pass: ReplaceBodyWithLoop
.
Before this pass, the name resolution pass creates a DefId
for the macro with the closure expression as parent:
fn main -> block -> closure -> block -> macrodef
But later on, during ReplaceBodyWithLoop
, the closure expression layer is removed and the AST ends up looking like:
fn main -> block -> block -> macrodef
Then, the macro is lowered but not its parent which explains why the closure DefId
does not have an associated HirId
.
As far as i know, this simplification pass is only used by rustdoc
.
When trying to fix https://github.com/rust-lang/rust/issues/71104 I ended up fighting with some rustdoc test about declarative macro: https://github.com/rust-lang/rust/blob/master/src/test/rustdoc/macro-in-closure.rs
The problem is that the macro is properly lowered to hir because its exported but the parent item is not:
DefId(0:5 ~ macro_in_closure[317d]::main[0]::{{closure}}[0]::m[0])
DefId(0:4 ~ macro_in_closure[317d]::main[0]::{{closure}}[0])
The latter appears nowhere in the hir tree and when https://github.com/rust-lang/rust/blob/master/src/librustc_privacy/lib.rs#L945 tries to access its parent, it returns a
DefId
that has no associatedHirId
.I don't know exactly how lowering of closure works, neither the details of declarative macro visibility, but i think the bug is either:
Here is a hir dump of the test case:
cc https://github.com/rust-lang/rust/issues/39412