diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 4ce7c70d4b57e..837cd034b655c 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 42a8832185ae6..d63e1ee60b3c5 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 c0241b98b78c1..6addb010e078f 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