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

Links in doc comments to proc_macro_attribute functions cause rustdoc panic #55399

Closed
antonok-edm opened this issue Oct 26, 2018 · 4 comments · Fixed by #57846
Closed

Links in doc comments to proc_macro_attribute functions cause rustdoc panic #55399

antonok-edm opened this issue Oct 26, 2018 · 4 comments · Fixed by #57846
Labels
A-intra-doc-links Area: Intra-doc links, the ability to link to items in docs by name A-macros-1.2 Area: Declarative macros 1.2 I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.

Comments

@antonok-edm
Copy link
Contributor

The following code builds successfully but causes a compiler panic when running cargo doc:
src/lib.rs

extern crate proc_macro;

/// [function_name]
#[proc_macro_attribute]
pub fn function_name(_attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
    item
}

Cargo.toml

[package]
name = "causes-rustdoc-panic"
version = "0.1.0"

[lib]
proc-macro = true

Compiler error

thread '<unnamed>' panicked at 'called `Option::unwrap()` on a `None` value', libcore/option.rs:355:21

Toolchain

rustc 1.31.0-nightly (4bd4e4130 2018-10-25) running on x86_64-unknown-linux-gnu

Changing function_name to another name, either in the doc comment or the actual function name (but not both), causes cargo doc to succeed with a warning that the link cannot be resolved, as expected.

Using a normal public function in a non-proc_macro library also does not cause a panic, e.g.

/// [function_name]
#[inline]
pub fn function_name(_attr: u8, item: u8) -> u8 {
    item
}
@memoryruins memoryruins added T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ labels Oct 29, 2018
@QuietMisdreavus QuietMisdreavus added the A-intra-doc-links Area: Intra-doc links, the ability to link to items in docs by name label Nov 9, 2018
@euclio
Copy link
Contributor

euclio commented Dec 23, 2018

Same stack trace as #54100.

@antonok-edm
Copy link
Contributor Author

@euclio Good find.

That one is also a procedural macro, might be appropriate to add a macro label to both.

@QuietMisdreavus
Copy link
Member

Doing a little digging...

The first rustdoc code in that stack trace is this part in macro_resolve, which attempts to load up a macro definition for the given path text:

if let Ok(def) = resolver.resolve_macro_to_def_inner(&path, MacroKind::Bang,
&parent_scope, false, false) {
if let SyntaxExtension::DeclMacro { .. } = *resolver.get_macro(def) {
return Some(def);
}
}

The call to resolve_macro_to_def_inner successfully returns a Def, but it's the call to get_macro that's ultimately failing. The reasoning behind this can be explained in the resolve_macro_to_def function, which we're not calling, but handles the same code with a bit more overhead. In that function, there's a branch that gives me a hint to what's going on:

Def::Macro(def_id, macro_kind) => {
self.unused_macros.remove(&def_id);
if macro_kind == MacroKind::ProcMacroStub {
let msg = "can't use a procedural macro from the same crate that defines it";
self.session.span_err(path.span, msg);
return Err(Determinacy::Determined);
}
}

In effect: proc-macros are not available to the crate that defines them. This makes sense in terms of making sure they don't infinitely recurse, but leaves rustdoc out to dry when all it wants is to make sure that the macro in question is a Macros 2.0 macro. I'm waiting on a build right now, but we may be able to skip the call to get_macro by looking at the Def returned by resolve_macro_to_def_inner and seeing whether it's a ProcMacroStub. That way, we can handle those differently and avoid the problematic call to get_macro.

@QuietMisdreavus
Copy link
Member

Update: Skipping the call to get_macro for macros of kind ProcMacroStub seems to have fixed this issue! I've opened #57846 to fix this.

Centril added a commit to Centril/rust that referenced this issue Jan 24, 2019
…=GuillaumeGomez

rustdoc: fix ICE from loading proc-macro stubs

Fixes rust-lang#55399

When trying to resolve a macro, rustdoc first tries to load it from the resolver to see whether it's a Macros 2.0 macro, so it can return that Def before looking for any other kind of macro. However, this becomes a problem when you try to load proc-macros: since you can't use a proc-macro inside its own crate, this lookup also fails when attempting to link to it.

However, we have a hint that this lookup will fail: Macros which are actually `ProcMacroStub`s will fail the lookup, so we can use that information to skip loading the macro. Rustdoc will then happily check `resolve.all_macros`, which will return a usable Def that we can link to.
@bors bors closed this as completed in e576c8c Jan 25, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-intra-doc-links Area: Intra-doc links, the ability to link to items in docs by name A-macros-1.2 Area: Declarative macros 1.2 I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants