From 6ac52f0d9dc2f3f8a423e3b54663f42ac4ebab05 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 24 Dec 2020 18:55:05 -0500 Subject: [PATCH] Don't process `[]` and `()` in intra-doc links These caused several false positives when documenting rustc, which means there will likely be many more false positives in the rest of the ecosystem. --- .../passes/collect_intra_doc_links.rs | 11 +-- .../intra-doc/non-path-primitives.rs | 34 +++++++++ .../intra-doc/non-path-primitives.stderr | 69 +++++++++++++++++++ .../rustdoc/intra-doc/non-path-primitives.rs | 27 -------- 4 files changed, 109 insertions(+), 32 deletions(-) create mode 100644 src/test/rustdoc-ui/intra-doc/non-path-primitives.rs create mode 100644 src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index b8db0d5a4d6..1fd0b3a2931 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1020,7 +1020,7 @@ impl LinkCollector<'_, '_> { (link.trim(), None) }; - if path_str.contains(|ch: char| !(ch.is_alphanumeric() || ":_<>, !*()[]&;".contains(ch))) { + if path_str.contains(|ch: char| !(ch.is_alphanumeric() || ":_<>, !*&;".contains(ch))) { return None; } @@ -2085,10 +2085,11 @@ fn resolve_primitive(path_str: &str, ns: Namespace) -> Option { "char" => Char, "bool" | "true" | "false" => Bool, "str" => Str, - "slice" | "&[]" | "[T]" => Slice, - "array" | "[]" | "[T;N]" => Array, - "tuple" | "(,)" => Tuple, - "unit" | "()" => Unit, + // See #80181 for why these don't have symbols associated. + "slice" => Slice, + "array" => Array, + "tuple" => Tuple, + "unit" => Unit, "pointer" | "*" | "*const" | "*mut" => RawPointer, "reference" | "&" | "&mut" => Reference, "fn" => Fn, diff --git a/src/test/rustdoc-ui/intra-doc/non-path-primitives.rs b/src/test/rustdoc-ui/intra-doc/non-path-primitives.rs new file mode 100644 index 00000000000..114502b0ddf --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/non-path-primitives.rs @@ -0,0 +1,34 @@ +#![deny(broken_intra_doc_links)] +// These are links that could reasonably expected to work, but don't. + +// `[]` isn't supported because it had too many false positives. +//! [X]([T]::not_here) +//! [Y](&[]::not_here) +//! [X]([]::not_here) +//! [Y]([T;N]::not_here) + +// These don't work because markdown syntax doesn't allow it. +//! [[T]::rotate_left] //~ ERROR unresolved link to `T` +//! [&[]::not_here] +//![Z]([T; N]::map) //~ ERROR unresolved link to `Z` +//! [`[T; N]::map`] +//! [[]::map] +//! [Z][] //~ ERROR unresolved link to `Z` +//! +//! [Z]: [T; N]::map //~ ERROR unresolved link to `Z` + +// `()` isn't supported because it had too many false positives. +//! [()::not_here] +//! [X]((,)::not_here) +//! [(,)::not_here] + +// FIXME: Associated items on some primitives aren't working, because the impls +// are part of the compiler instead of being part of the source code. +//! [unit::eq] //~ ERROR unresolved +//! [tuple::eq] //~ ERROR unresolved +//! [fn::eq] //~ ERROR unresolved +//! [never::eq] //~ ERROR unresolved + +// FIXME(#78800): This breaks because it's a blanket impl +// (I think? Might break for other reasons too.) +//! [reference::deref] //~ ERROR unresolved diff --git a/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr b/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr new file mode 100644 index 00000000000..ea831e648f6 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr @@ -0,0 +1,69 @@ +error: unresolved link to `T` + --> $DIR/non-path-primitives.rs:11:7 + | +LL | //! [[T]::rotate_left] + | ^ no item named `T` in scope + | +note: the lint level is defined here + --> $DIR/non-path-primitives.rs:1:9 + | +LL | #![deny(broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^ + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `Z` + --> $DIR/non-path-primitives.rs:13:5 + | +LL | //![Z]([T; N]::map) + | ^ no item named `Z` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `Z` + --> $DIR/non-path-primitives.rs:16:6 + | +LL | //! [Z][] + | ^ no item named `Z` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `Z` + --> $DIR/non-path-primitives.rs:18:6 + | +LL | //! [Z]: [T; N]::map + | ^ no item named `Z` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `unit::eq` + --> $DIR/non-path-primitives.rs:27:6 + | +LL | //! [unit::eq] + | ^^^^^^^^ the builtin type `unit` has no associated item named `eq` + +error: unresolved link to `tuple::eq` + --> $DIR/non-path-primitives.rs:28:6 + | +LL | //! [tuple::eq] + | ^^^^^^^^^ the builtin type `tuple` has no associated item named `eq` + +error: unresolved link to `fn::eq` + --> $DIR/non-path-primitives.rs:29:6 + | +LL | //! [fn::eq] + | ^^^^^^ the builtin type `fn` has no associated item named `eq` + +error: unresolved link to `never::eq` + --> $DIR/non-path-primitives.rs:30:6 + | +LL | //! [never::eq] + | ^^^^^^^^^ the builtin type `never` has no associated item named `eq` + +error: unresolved link to `reference::deref` + --> $DIR/non-path-primitives.rs:34:6 + | +LL | //! [reference::deref] + | ^^^^^^^^^^^^^^^^ the builtin type `reference` has no associated item named `deref` + +error: aborting due to 9 previous errors + diff --git a/src/test/rustdoc/intra-doc/non-path-primitives.rs b/src/test/rustdoc/intra-doc/non-path-primitives.rs index 83d081824ff..ad4f6ddd9de 100644 --- a/src/test/rustdoc/intra-doc/non-path-primitives.rs +++ b/src/test/rustdoc/intra-doc/non-path-primitives.rs @@ -3,28 +3,10 @@ #![deny(broken_intra_doc_links)] // @has foo/index.html '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.rotate_left"]' 'slice::rotate_left' -// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.rotate_left"]' 'X' -// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.rotate_left"]' 'Y' //! [slice::rotate_left] -//! [X]([T]::rotate_left) -//! [Y](&[]::rotate_left) -// These don't work because markdown syntax doesn't allow it. -// [[T]::rotate_left] -//! [&[]::rotate_left] // @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.array.html#method.map"]' 'array::map' -// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.array.html#method.map"]' 'X' -// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.array.html#method.map"]' 'Y' //! [array::map] -//! [X]([]::map) -//! [Y]([T;N]::map) -// These don't work because markdown syntax doesn't allow it. -// [Z]([T; N]::map) -//! [`[T; N]::map`] -//! [[]::map] -// [Z][] -// -// [Z]: [T; N]::map // @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.is_null"]' 'pointer::is_null' // @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.is_null"]' '*const::is_null' @@ -35,20 +17,11 @@ //! [*mut::is_null] //! [*::is_null] -// FIXME: Associated items on some primitives aren't working, because the impls -// are part of the compiler instead of being part of the source code. - // @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.unit.html"]' 'unit' -// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.unit.html"]' '()' //! [unit] -//! [()] // @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.tuple.html"]' 'tuple' -// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.tuple.html"]' 'X' -// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.tuple.html"]' '(,)' //! [tuple] -//! [X]((,)) -//! [(,)] // @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.reference.html"]' 'reference' // @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.reference.html"]' '&'