about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJoshua Nelson <jyn514@gmail.com>2021-04-14 16:59:41 -0400
committerJoshua Nelson <jyn514@gmail.com>2021-04-17 16:03:03 -0400
commit59546efaa3bbbad5fdcd2a95346c87f5bb2b9511 (patch)
treea660e0b6a94af49ab2677f9fbbd97ce1867ec8c5
parent9c3b66cff74f3a21dc735294f3df319a38bc2114 (diff)
downloadrust-59546efaa3bbbad5fdcd2a95346c87f5bb2b9511.tar.gz
rust-59546efaa3bbbad5fdcd2a95346c87f5bb2b9511.zip
rustdoc: Give a more accurate span for anchor failures
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs24
-rw-r--r--src/test/rustdoc-ui/intra-doc/anchors.stderr20
-rw-r--r--src/test/rustdoc-ui/intra-doc/double-anchor.stderr4
3 files changed, 34 insertions, 14 deletions
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 4ce7c70d4b5..837cd034b65 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1957,20 +1957,28 @@ fn resolution_failure(
 
 /// Report an anchor failure.
 fn anchor_failure(cx: &DocContext<'_>, diag_info: DiagnosticInfo<'_>, failure: AnchorFailure) {
-    let msg = match failure {
+    let (msg, anchor_idx) = match failure {
         AnchorFailure::MultipleAnchors => {
-            format!("`{}` contains multiple anchors", diag_info.ori_link)
+            (format!("`{}` contains multiple anchors", diag_info.ori_link), 1)
         }
-        AnchorFailure::RustdocAnchorConflict(res) => format!(
-            "`{}` contains an anchor, but links to {kind}s are already anchored",
-            diag_info.ori_link,
-            kind = res.descr(),
+        AnchorFailure::RustdocAnchorConflict(res) => (
+            format!(
+                "`{}` contains an anchor, but links to {kind}s are already anchored",
+                diag_info.ori_link,
+                kind = res.descr(),
+            ),
+            0,
         ),
     };
 
     report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, &msg, &diag_info, |diag, sp| {
-        if let Some(sp) = sp {
-            diag.span_label(sp, "contains invalid anchor");
+        if let Some(mut sp) = sp {
+            if let Some((fragment_offset, _)) =
+                diag_info.ori_link.char_indices().filter(|(_, x)| *x == '#').nth(anchor_idx)
+            {
+                sp = sp.with_lo(sp.lo() + rustc_span::BytePos(fragment_offset as _));
+            }
+            diag.span_label(sp, "invalid anchor");
         }
         if let AnchorFailure::RustdocAnchorConflict(Res::Primitive(_)) = failure {
             diag.note("this restriction may be lifted in a future release");
diff --git a/src/test/rustdoc-ui/intra-doc/anchors.stderr b/src/test/rustdoc-ui/intra-doc/anchors.stderr
index 42a8832185a..d63e1ee60b3 100644
--- a/src/test/rustdoc-ui/intra-doc/anchors.stderr
+++ b/src/test/rustdoc-ui/intra-doc/anchors.stderr
@@ -2,7 +2,9 @@ error: `prim@usize#x` contains an anchor, but links to builtin types are already
   --> $DIR/anchors.rs:47:6
    |
 LL | /// [prim@usize#x]
-   |      ^^^^^^^^^^^^ contains invalid anchor
+   |      ^^^^^^^^^^--
+   |                |
+   |                invalid anchor
    |
 note: the lint level is defined here
   --> $DIR/anchors.rs:1:9
@@ -16,25 +18,33 @@ error: `Foo::f#hola` contains an anchor, but links to fields are already anchore
   --> $DIR/anchors.rs:25:15
    |
 LL | /// Or maybe [Foo::f#hola].
-   |               ^^^^^^^^^^^ contains invalid anchor
+   |               ^^^^^^-----
+   |                     |
+   |                     invalid anchor
 
 error: `hello#people#!` contains multiple anchors
   --> $DIR/anchors.rs:31:28
    |
 LL | /// Another anchor error: [hello#people#!].
-   |                            ^^^^^^^^^^^^^^ contains invalid anchor
+   |                            ^^^^^^^^^^^^--
+   |                                        |
+   |                                        invalid anchor
 
 error: `Enum::A#whatever` contains an anchor, but links to variants are already anchored
   --> $DIR/anchors.rs:37:28
    |
 LL | /// Damn enum's variants: [Enum::A#whatever].
-   |                            ^^^^^^^^^^^^^^^^ contains invalid anchor
+   |                            ^^^^^^^---------
+   |                                   |
+   |                                   invalid anchor
 
 error: `u32#hello` contains an anchor, but links to builtin types are already anchored
   --> $DIR/anchors.rs:43:6
    |
 LL | /// [u32#hello]
-   |      ^^^^^^^^^ contains invalid anchor
+   |      ^^^------
+   |         |
+   |         invalid anchor
    |
    = note: this restriction may be lifted in a future release
    = note: see https://github.com/rust-lang/rust/issues/83083 for more information
diff --git a/src/test/rustdoc-ui/intra-doc/double-anchor.stderr b/src/test/rustdoc-ui/intra-doc/double-anchor.stderr
index c0241b98b78..6addb010e07 100644
--- a/src/test/rustdoc-ui/intra-doc/double-anchor.stderr
+++ b/src/test/rustdoc-ui/intra-doc/double-anchor.stderr
@@ -2,7 +2,9 @@ warning: `with#anchor#error` contains multiple anchors
   --> $DIR/double-anchor.rs:5:18
    |
 LL | /// docs [label][with#anchor#error]
-   |                  ^^^^^^^^^^^^^^^^^ contains invalid anchor
+   |                  ^^^^^^^^^^^------
+   |                             |
+   |                             invalid anchor
    |
    = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default