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

rustdoc: Unify macro intra-doc link resolution with type and value resolution #91427

Closed
wants to merge 5 commits into from

Conversation

jyn514
Copy link
Member

@jyn514 jyn514 commented Dec 1, 2021

Fixes #81633 and also cleans up quite a lot of code.

r? @Manishearth

rustdoc should already have error-ed out for conflicting anchors, and it
doesn't make sense to do this for only one namespace anyway.
@jyn514 jyn514 added T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) A-intra-doc-links Area: Intra-doc links, the ability to link to items in docs by name labels Dec 1, 2021
@rust-highfive
Copy link
Collaborator

Some changes occurred in intra-doc-links.

cc @jyn514

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Dec 1, 2021
@jyn514
Copy link
Member Author

jyn514 commented Dec 1, 2021

Oh, this can probably remove the all_macros field on the resolver too - cc @petrochenkov

@rust-log-analyzer
Copy link
Collaborator

The job x86_64-gnu-llvm-12 failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
 Documenting core v0.0.0 (/checkout/library/core)
error: unresolved link to `unreachable`
  --> library/core/src/hint.rs:25:37
   |
25 | /// Otherwise, consider using the [`unreachable!`] macro, which does not allow
   |                                     ^^^^^^^^^^^^ no item named `unreachable` in scope
   |
   = note: `-D rustdoc::broken-intra-doc-links` implied by `-D warnings`
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
error: unresolved link to `write`
   --> library/core/src/fmt/mod.rs:166:33
    |
    |
166 |     /// Glue for usage of the [`write!`] macro with implementors of this trait.
    |                                 ^^^^^^ this link resolves to the function `write`, which is not in the macro namespace
help: to link to the function, add parentheses
    |
    |
166 |     /// Glue for usage of the [`write!()`] macro with implementors of this trait.

error: unresolved link to `write`
   --> library/core/src/fmt/mod.rs:169:15
    |
    |
169 |     /// the [`write!`] macro itself.
    |               ^^^^^^ this link resolves to the function `write`, which is not in the macro namespace
help: to link to the function, add parentheses
    |
    |
169 |     /// the [`write!()`] macro itself.

error: unresolved link to `panic`
   --> library/core/src/macros/mod.rs:171:28
    |
    |
171 | /// This will invoke the [`panic!`] macro if the provided expression cannot be
    |                            ^^^^^^ no item named `panic` in scope
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

error: unresolved link to `assert_eq`
    |
    |
223 | /// Unlike [`assert_eq!`], `debug_assert_eq!` statements are only enabled in non
    |              ^^^^^^^^^^ no item named `assert_eq` in scope
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

error: unresolved link to `assert_ne`
    |
    |
248 | /// Unlike [`assert_ne!`], `debug_assert_ne!` statements are only enabled in non
    |              ^^^^^^^^^^ no item named `assert_ne` in scope
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
error: unresolved link to `write`
   --> library/core/src/macros/mod.rs:487:33
    |
    |
487 | /// For more information, see [`write!`]. For information on the format string syntax, see
    |
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
error: unresolved link to `panic`
   --> library/core/src/macros/mod.rs:548:45
    |
    |
548 | /// program immediately terminates with a [`panic!`].
    |                                             ^^^^^^ no item named `panic` in scope
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
error: unresolved link to `panic`
   --> library/core/src/macros/mod.rs:557:24
    |
    |
557 | /// This will always [`panic!`] because `unreachable!` is just a shorthand for `panic!` with a
    |                        ^^^^^^ no item named `panic` in scope
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

error: unresolved link to `todo`
    |
    |
609 | /// The difference between `unimplemented!` and [`todo!`] is that while `todo!`
    |                                                   ^^^^^ no item named `todo` in scope
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
error: unresolved link to `panic`
   --> library/core/src/macros/mod.rs:616:24
    |
    |
616 | /// This will always [`panic!`] because `unimplemented!` is just a shorthand for `panic!` with a
    |                        ^^^^^^ no item named `panic` in scope
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

error: unresolved link to `unimplemented`
    |
    |
687 | /// The difference between [`unimplemented!`] and `todo!` is that while `todo!` conveys
    |                              ^^^^^^^^^^^^^^ no item named `unimplemented` in scope
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
error: unresolved link to `panic`
   --> library/core/src/macros/mod.rs:694:24
    |
    |
694 | /// This will always [`panic!`].
    |                        ^^^^^^ no item named `panic` in scope
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
error: unresolved link to `panic`
   --> library/core/src/macros/mod.rs:753:91
    |
    |
753 |     /// better error messages for erroneous conditions. It's the compiler-level form of [`panic!`],
    |                                                                                           ^^^^^^ no item named `panic` in scope
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
error: unresolved link to `write`
   --> library/core/src/macros/mod.rs:801:53
    |
    |
801 |     /// All other formatting macros ([`format!`], [`write!`], [`println!`], etc) are
    |
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
error: unresolved link to `panic`
    --> library/core/src/macros/mod.rs:1282:32
     |
     |
1282 |     /// This will invoke the [`panic!`] macro if the provided expression cannot be
     |                                ^^^^^^ no item named `panic` in scope
     |
     = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
error: unresolved link to `debug_assert`
    --> library/core/src/macros/mod.rs:1288:28
     |
     |
1288 |     /// be disabled. See [`debug_assert!`] for assertions that are not enabled in
     |                            ^^^^^^^^^^^^^ no item named `debug_assert` in scope
     |
     = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
error: could not document `core`

Caused by:
Caused by:
  process didn't exit successfully: `/checkout/obj/build/bootstrap/debug/rustdoc --edition=2018 --crate-type lib --crate-name core library/core/src/lib.rs --target x86_64-unknown-linux-gnu -o /checkout/obj/build/x86_64-unknown-linux-gnu/stage2-std/x86_64-unknown-linux-gnu/doc --error-format=json --json=diagnostic-rendered-ansi --markdown-css rust.css --markdown-no-toc -Z unstable-options --resource-suffix 1.59.0 --index-page /checkout/src/doc/index.md -L dependency=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-std/x86_64-unknown-linux-gnu/release/deps -L dependency=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-std/release/deps -Zsymbol-mangling-version=legacy -Dwarnings '-Wrustdoc::invalid_codeblock_attributes' --crate-version '1.59.0-nightly
  (b782ab7fa
  2021-12-01)' '-Zcrate-attr=doc(html_root_url="https://doc.rust-lang.org/nightly/")'` (exit status: 1)


command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "rustdoc" "--target" "x86_64-unknown-linux-gnu" "-Zbinary-dep-depinfo" "-j" "16" "--release" "--locked" "--color" "always" "--features" "panic-unwind backtrace compiler-builtins-c" "--manifest-path" "/checkout/library/test/Cargo.toml" "-p" "core" "-Zskip-rustdoc-fingerprint" "--" "--markdown-css" "rust.css" "--markdown-no-toc" "-Z" "unstable-options" "--resource-suffix" "1.59.0" "--index-page" "/checkout/src/doc/index.md"


Build completed unsuccessfully in 0:31:53

@jyn514
Copy link
Member Author

jyn514 commented Dec 1, 2021

Hmm, it looks like resolve_str_path_error doesn't consider #[macro_export] ... @petrochenkov would it be easy to make it do that or should I revert all the rustdoc changes and add back the call to resolve_macro_path?

@jyn514
Copy link
Member Author

jyn514 commented Dec 1, 2021

MCVE:

#[macro_export]
macro_rules! foo {
    () => {};
}


pub mod bar {
    /// [foo!]
    pub fn baz() {
        foo!();
    }
}

Rustc compiles the foo! invocation fine, rustdoc thinks it's a broken link.

Copy link
Member

@Manishearth Manishearth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sweet, i always disliked this setup

self.cx.enter_resolver(|resolver| {
// FIXME(jynelson): does this really need 3 separate lookups?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

turns out, no 😆

None,
&ParentScope::module(resolver.graph_root(), resolver),
false,
false,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps we should also add tests that ensure that macros can still be linked to on both newer and older editions

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yeah, you noted a problem with #[macro_export] above

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this code was like this to handle macro_export/old-style macro resolution. Which still exists. But perhaps we can handle this a bit cleaner.

@petrochenkov
Copy link
Contributor

Hmm, it looks like resolve_str_path_error doesn't consider #[macro_export]

macro_export is irrelevant, resolve_str_path_error doesn't consider non-modularized macro_rules scopes in general.

{
    struct S;

    macro_rules! mac { () => {} }
    // `mac`'s scope starts here

    /// `mac` <- `resolve_str_path_error` won't see this
   struct Z;

    //`mac`'s scope ends here
}

As you can see fn resolve_str_path_error will construct the scope in which the path is resolved using ParentScope::module, which leaves the macro_rules component of ParentScope empty.
Ideally the current macro_rules scope should be specifically tracked and updated in the current ParentScope like it's done in BuildReducedGraphVisitor, for example.

So both using and not using all_macros is wrong, but what is more wrong depends on whether you like false positives or false negatives more.

@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 2, 2021
@petrochenkov
Copy link
Contributor

Ideally the current macro_rules scope should be specifically tracked and updated in the current ParentScope

This will be very easy to do for local macro_rules after link resolution is moved to early.rs, BTW.

This will be hard to do for links inlined from other crates, because we don't even keep the relevant information in metadata (although we may start keeping it due to macros 2.0).

@bors
Copy link
Contributor

bors commented Jan 11, 2022

☔ The latest upstream changes (presumably #92601) made this pull request unmergeable. Please resolve the merge conflicts.

@JohnCSimon
Copy link
Member

JohnCSimon commented Feb 6, 2022

merge conflicts + broken build.

@jyn514
Copy link
Member Author

jyn514 commented Feb 6, 2022

yes, I'm aware, that's why it's marked waiting-on-author.

@petrochenkov
Copy link
Contributor

Any chance to get this landed with all_macros kept and being used as a fallback if regular resolution fails?
It would be very helpful for "rustdoc: Stop cloning the resolver".

@jyn514
Copy link
Member Author

jyn514 commented Feb 6, 2022

@petrochenkov I don't know when I'll get a chance to work on this. Feel free to take over the PR and have someone from the rustdoc team review.

@jyn514
Copy link
Member Author

jyn514 commented Feb 7, 2022

Ok I take it back, I can do this much:

Any chance to get this landed with all_macros kept and being used as a fallback if regular resolution fails?

Not sure how that's helpful for the resolver hackery, since it still requires access to the resolver in resolve_macro, but it's easy enough. I'm not planning to work on removing all_macros.

@petrochenkov
Copy link
Contributor

Not sure how that's helpful for the resolver hackery

It removes the use of resolve_macro_path and leaves resolve_str_path_error as the only used resolution method.

@jyn514
Copy link
Member Author

jyn514 commented Feb 7, 2022

macro_export is irrelevant, resolve_str_path_error doesn't consider non-modularized macro_rules scopes in general.

I'm not sure in what context you could document a non-modularized macro. Rustdoc doesn't document anything at function-scope, only at the module level. I don't understand why the macro in the MCVE (#91427 (comment)) isn't resolved according to the rules you explained.

@Manishearth
Copy link
Member

I may also have time later to do some rebasing and patchups here if necessary, but not any time soon.

@jyn514
Copy link
Member Author

jyn514 commented Feb 7, 2022

@Manishearth this requires more than patchups, someone needs to investigate why the MCVE doesn't work and then figure out how to change the resolver internals to make it work with resolve_str_path_error.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Feb 8, 2022
…=petrochenkov

rustdoc: Special-case macro lookups less

Previously, rustdoc had 3 fallbacks it used:
1. `resolve_macro_path`
2. `all_macros`
3. `resolve_str_path_error`

Ideally, it would only use `resolve_str_path_error`, to be consistent with other namespaces.
Unfortunately, that doesn't consider macros that aren't defined at module scope;
consider for instance
```rust
{
    struct S;

    macro_rules! mac { () => {} }
    // `mac`'s scope starts here

    /// `mac` <- `resolve_str_path_error` won't see this
   struct Z;

    //`mac`'s scope ends here
}
```

This changes it to only use `all_macros` and `resolve_str_path_error`, and gives
`resolve_str_path_error` precedence over `all_macros` in case there are two macros with the same
name in the same module.

This is a smaller version of rust-lang#91427.

r? `@petrochenkov`
@jyn514
Copy link
Member Author

jyn514 commented Feb 11, 2022

Not planning to look into this. Happy for someone else to pick it up.

@jyn514 jyn514 closed this Feb 11, 2022
@jyn514 jyn514 deleted the macro-link-scoping branch April 25, 2022 16:28
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 Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

private macros break intra-doc links
7 participants