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

get rid of some false negatives in rustdoc::broken_intra_doc_links #132748

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

lolbinarycat
Copy link
Contributor

@lolbinarycat lolbinarycat commented Nov 7, 2024

rustdoc will not try to do intra-doc linking if the "path" of a link looks too much like a "real url".

however, only inline links (text) can actually contain a url, other types of links (reference links, shortcut links) contain a reference which is later resolved to an actual url.

the "path" in this case cannot be a url, and therefore it should not be skipped due to looking like a url.

fixes #54191

@rustbot
Copy link
Collaborator

rustbot commented Nov 7, 2024

r? @notriddle

rustbot has assigned @notriddle.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Nov 7, 2024
rustdoc will not try to do intra-doc linking if the "path"
of a link looks too much like a "real url".

however, only inline links ([text](url)) can actually contain
a url, other types of links (reference links, shortcut links)
contain a *reference* which is later resolved to an actual url.

the "path" in this case cannot be a url, and therefore it should
not be skipped due to looking like a url.

fixes rust-lang#54191
@lolbinarycat lolbinarycat force-pushed the rustdoc-intra-doc-link-warn-more-54191 branch from df3d0f6 to 8ae6586 Compare November 7, 2024 21:41
@rust-log-analyzer

This comment has been minimized.

Copy link
Contributor

@notriddle notriddle left a comment

Choose a reason for hiding this comment

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

This looks like a good idea, but I have found one problem. Consider a sample like this:

//@ check-pass
#![no_std]
#![deny(rustdoc::broken_intra_doc_links)]

// regression test for https://github.com/rust-lang/rust/issues/54191
// false positives

//! This is not an intra-doc link: [`foobar`]
//!
//! [`foobar`]: /index.html

That test case fails, because it thinks /index.html is an intra-doc link. You're right that certain kinds of links aren't allowed to be URLs—that's the Unknown type links.

src/librustdoc/passes/collect_intra_doc_links.rs Outdated Show resolved Hide resolved
tests/rustdoc-ui/bad-intra-doc.rs Outdated Show resolved Hide resolved
@rustbot rustbot 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 Nov 7, 2024
lolbinarycat and others added 2 commits November 7, 2024 16:26
fix link kind check

Co-authored-by: Michael Howell <[email protected]>
add error annotation

Co-authored-by: Michael Howell <[email protected]>
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@lolbinarycat
Copy link
Contributor Author

welp, turns out the standard library itself contains several of these false negatives!

@lolbinarycat
Copy link
Contributor Author

...or perhaps there's some deeper bug with intra-doc link generation?

there seems to be some false positives containing spaces, even though there is a matching reference definition...

I guess we can just re-enable unconditionally ignoring links with spaces?

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@lolbinarycat
Copy link
Contributor Author

Ok, this breaks a lot of ui tests. This might actually have a pretty big impact, maybe we should do a crater run or something..?

@lolbinarycat lolbinarycat added S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Nov 8, 2024
@notriddle
Copy link
Contributor

It's looks fine to me. Here's the PRs where each of these test cases were added:

test case PR
disambiguator-endswith-named-suffix.rs #127016
weird-syntax.rs #112014
redundant_explicit_links-utf8.rs #115070

The last two are both contrived ICE tests, and all of them are intended to be parsed as intra-doc links. Making it so that they warn seems fine to me.

r? @GuillaumeGomez do you also think this is a suitable bug fix?

@rustbot rustbot assigned GuillaumeGomez and unassigned notriddle Nov 8, 2024
@notriddle notriddle self-assigned this Nov 8, 2024
@GuillaumeGomez
Copy link
Member

I think so. I'm not completely satisfied with the current impact though. Intra-doc links should not be triggered on items that contain characters which can't be in an ident or a path, like Clone\(\). Maybe a different warning in these cases?

@lolbinarycat
Copy link
Contributor Author

@GuillaumeGomez what about just amending the current warning to account for other common mistakes?

honestly makes me wish we had --explain for lints, putting a full help message for each one could get a bit verbose.

regardless, i think that should be a separate issue, since the lint output isn't the most helpful in general (it just recommends escaping the brackets, and doesn't mention other common issues, such as misspelled link references)

@GuillaumeGomez
Copy link
Member

what about just amending the current warning to account for other common mistakes?

Do you have an example of before/after of what you have in mind by any chance?

@lolbinarycat
Copy link
Contributor Author

Do you have an example of before/after of what you have in mind by any chance?

well, the most obvious one is some sort of "consider adding a reference: [whatever]: //some-url.example/", but i also think trying to catch typos by comparing the edit distance of the missing reference to that of existing references could be handy.

and perhaps we should also mention surrounding code by backticks, since code snippets should generally be in code blocks instead of individually escaping chars.

@GuillaumeGomez
Copy link
Member

well, the most obvious one is some sort of "consider adding a reference: [whatever]: //some-url.example/", but i also think trying to catch typos by comparing the edit distance of the missing reference to that of existing references could be handy.

Sounds good to me. The distance between two items could be nice too (as a follow-up?).

@lolbinarycat
Copy link
Contributor Author

opened #132788 to track future improvements to this lint.

@rust-log-analyzer
Copy link
Collaborator

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

Click to see the possible cause of the failure (guessed by this bot)
------
 > importing cache manifest from ghcr.io/rust-lang/rust-ci-cache:c32c805632780b5c1de330e3f44561b336c2efe163bc0990acb392390157a8e1d9f855d75914a239aa40c49d77f4a837247d05d2f8d46f554b98e1f46712a3e3:
------
##[endgroup]
Setting extra environment values for docker:  --env ENABLE_GCC_CODEGEN=1 --env GCC_EXEC_PREFIX=/usr/lib/gcc/
[CI_JOB_NAME=x86_64-gnu-llvm-18]
debug: `DISABLE_CI_RUSTC_IF_INCOMPATIBLE` configured.
---
sccache: Starting the server...
##[group]Configure the build
configure: processing command line
configure: 
configure: build.configure-args := ['--build=x86_64-unknown-linux-gnu', '--llvm-root=/usr/lib/llvm-18', '--enable-llvm-link-shared', '--set', 'rust.randomize-layout=true', '--set', 'rust.thin-lto-import-instr-limit=10', '--enable-verbose-configure', '--enable-sccache', '--disable-manage-submodules', '--enable-locked-deps', '--enable-cargo-native-static', '--set', 'rust.codegen-units-std=1', '--set', 'dist.compression-profile=balanced', '--dist-compression-formats=xz', '--set', 'rust.lld=false', '--disable-dist-src', '--release-channel=nightly', '--enable-debug-assertions', '--enable-overflow-checks', '--enable-llvm-assertions', '--set', 'rust.verify-llvm-ir', '--set', 'rust.codegen-backends=llvm,cranelift,gcc', '--set', 'llvm.static-libstdcpp', '--enable-new-symbol-mangling']
configure: target.x86_64-unknown-linux-gnu.llvm-config := /usr/lib/llvm-18/bin/llvm-config
configure: llvm.link-shared     := True
configure: rust.randomize-layout := True
configure: rust.thin-lto-import-instr-limit := 10
---
  Downloaded boml v0.3.1
   Compiling boml v0.3.1
   Compiling y v0.1.0 (/checkout/compiler/rustc_codegen_gcc/build_system)
    Finished `release` profile [optimized] target(s) in 3.68s
     Running `/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-codegen/x86_64-unknown-linux-gnu/release/y test --use-system-gcc --use-backend gcc --out-dir /checkout/obj/build/x86_64-unknown-linux-gnu/stage1-tools/cg_gcc --release --mini-tests --std-tests`
Using system GCC
[BUILD] example
[AOT] mini_core_hello_world
/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-tools/cg_gcc/mini_core_hello_world
abc
---
37 
+ error: unresolved link to `()::not_here`
+   --> $DIR/non-path-primitives.rs:22:6
+    |
+ LL | //! [()::not_here]
+ 
+ 
+ error: unresolved link to `(,)::not_here`
+    |
+    |
+ LL | //! [(,)::not_here]
+    |      ^^^^^^^^^^^^^ no item named `(,)` in scope
38 error: unresolved link to `unit::eq`
39   --> $DIR/non-path-primitives.rs:28:6
40    |


59 LL | //! [reference::deref]
60    |      ^^^^^^^^^^^^^^^^ the primitive type `reference` has no associated item named `deref`
- error: aborting due to 8 previous errors
+ error: aborting due to 10 previous errors
63 
64 
---
To only update this specific test, also pass `--test-args intra-doc/non-path-primitives.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustdoc" "/checkout/tests/rustdoc-ui/intra-doc/non-path-primitives.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2" "--target=x86_64-unknown-linux-gnu" "--check-cfg" "cfg(FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/rustdoc-ui/intra-doc/non-path-primitives" "-A" "internal_features" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers"
--- stderr -------------------------------
error: unresolved link to `T`
##[error]  --> /checkout/tests/rustdoc-ui/intra-doc/non-path-primitives.rs:12:7
   |
   |
LL | //! [[T]::rotate_left] //~ ERROR unresolved link to `T`
   |       ^ no item named `T` in scope
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
note: the lint level is defined here
  --> /checkout/tests/rustdoc-ui/intra-doc/non-path-primitives.rs:1:9
   |
   |
LL | #![deny(rustdoc::broken_intra_doc_links)]
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: unresolved link to `Z`
##[error]  --> /checkout/tests/rustdoc-ui/intra-doc/non-path-primitives.rs:14:5
   |
LL | //![Z]([T; N]::map) //~ ERROR unresolved link to `Z`
   |     ^ no item named `Z` in scope
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

error: unresolved link to `Z`
##[error]  --> /checkout/tests/rustdoc-ui/intra-doc/non-path-primitives.rs:17:6
##[error]  --> /checkout/tests/rustdoc-ui/intra-doc/non-path-primitives.rs:17:6
   |
LL | //! [Z][] //~ ERROR unresolved link to `Z`
   |      ^ no item named `Z` in scope
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

error: unresolved link to `Z`
##[error]  --> /checkout/tests/rustdoc-ui/intra-doc/non-path-primitives.rs:19:6
##[error]  --> /checkout/tests/rustdoc-ui/intra-doc/non-path-primitives.rs:19:6
   |
LL | //! [Z]: [T; N]::map //~ ERROR unresolved link to `Z`
   |      ^ no item named `Z` in scope
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

error: unresolved link to `()::not_here`
##[error]  --> /checkout/tests/rustdoc-ui/intra-doc/non-path-primitives.rs:22:6
##[error]  --> /checkout/tests/rustdoc-ui/intra-doc/non-path-primitives.rs:22:6
   |
LL | //! [()::not_here]


error: unresolved link to `(,)::not_here`
   |
   |
LL | //! [(,)::not_here]
   |      ^^^^^^^^^^^^^ no item named `(,)` in scope
error: unresolved link to `unit::eq`
##[error]  --> /checkout/tests/rustdoc-ui/intra-doc/non-path-primitives.rs:28:6
   |
   |
LL | //! [unit::eq] //~ ERROR unresolved
   |      ^^^^^^^^ the primitive type `unit` has no associated item named `eq`
error: unresolved link to `tuple::eq`
##[error]  --> /checkout/tests/rustdoc-ui/intra-doc/non-path-primitives.rs:29:6
   |
   |
LL | //! [tuple::eq] //~ ERROR unresolved
   |      ^^^^^^^^^ the primitive type `tuple` has no associated item named `eq`
error: unresolved link to `fn::eq`
##[error]  --> /checkout/tests/rustdoc-ui/intra-doc/non-path-primitives.rs:30:6
   |
   |
LL | //! [fn::eq] //~ ERROR unresolved
   |      ^^^^^^ the primitive type `fn` has no associated item named `eq`
error: unresolved link to `reference::deref`
##[error]  --> /checkout/tests/rustdoc-ui/intra-doc/non-path-primitives.rs:34:6
   |
   |
LL | //! [reference::deref] //~ ERROR unresolved
   |      ^^^^^^^^^^^^^^^^ the primitive type `reference` has no associated item named `deref`
error: aborting due to 10 previous errors
------------------------------------------


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). 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.

rustdoc does not warn about broken links if they contain . or []
5 participants