about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustdoc/html/markdown.rs1
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs39
-rw-r--r--src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr17
3 files changed, 35 insertions, 22 deletions
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index b39f9f87892..c44514ed3cb 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -1162,6 +1162,7 @@ crate fn plain_text_summary(md: &str) -> String {
     s
 }
 
+#[derive(Debug)]
 crate struct MarkdownLink {
     pub kind: LinkType,
     pub link: String,
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index f5c5c9ca4aa..417637d2384 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -950,6 +950,7 @@ impl LinkCollector<'_, '_> {
         }
 
         let link = ori_link.link.replace("`", "");
+        let no_backticks_range = range_between_backticks(&ori_link);
         let parts = link.split('#').collect::<Vec<_>>();
         let (link, extra_fragment) = if parts.len() > 2 {
             // A valid link can't have multiple #'s
@@ -976,8 +977,10 @@ impl LinkCollector<'_, '_> {
         let (mut path_str, disambiguator) = match Disambiguator::from_str(&link) {
             Ok(Some((d, path))) => (path.trim(), Some(d)),
             Ok(None) => (link.trim(), None),
-            Err(err_msg) => {
-                disambiguator_error(self.cx, &item, dox, ori_link.range, &err_msg);
+            Err((err_msg, relative_range)) => {
+                let disambiguator_range = (no_backticks_range.start + relative_range.start)
+                    ..(no_backticks_range.start + relative_range.end);
+                disambiguator_error(self.cx, &item, dox, disambiguator_range, &err_msg);
                 return None;
             }
         };
@@ -1491,6 +1494,27 @@ impl LinkCollector<'_, '_> {
     }
 }
 
+/// Get the section of a link between the backticks,
+/// or the whole link if there aren't any backticks.
+///
+/// For example:
+///
+/// ```text
+/// [`Foo`]
+///   ^^^
+/// ```
+fn range_between_backticks(ori_link: &MarkdownLink) -> Range<usize> {
+    let after_first_backtick_group = ori_link.link.bytes().position(|b| b != b'`').unwrap_or(0);
+    let before_second_backtick_group = ori_link
+        .link
+        .bytes()
+        .skip(after_first_backtick_group)
+        .position(|b| b == b'`')
+        .unwrap_or(ori_link.link.len());
+    (ori_link.range.start + after_first_backtick_group)
+        ..(ori_link.range.start + before_second_backtick_group)
+}
+
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 /// Disambiguators for a link.
 enum Disambiguator {
@@ -1522,7 +1546,7 @@ impl Disambiguator {
     /// This returns `Ok(Some(...))` if a disambiguator was found,
     /// `Ok(None)` if no disambiguator was found, or `Err(...)`
     /// if there was a problem with the disambiguator.
-    fn from_str(link: &str) -> Result<Option<(Self, &str)>, String> {
+    fn from_str(link: &str) -> Result<Option<(Self, &str)>, (String, Range<usize>)> {
         use Disambiguator::{Kind, Namespace as NS, Primitive};
 
         let find_suffix = || {
@@ -1558,7 +1582,7 @@ impl Disambiguator {
                 "value" => NS(Namespace::ValueNS),
                 "macro" => NS(Namespace::MacroNS),
                 "prim" | "primitive" => Primitive,
-                _ => return Err(format!("unknown disambiguator `{}`", prefix)),
+                _ => return Err((format!("unknown disambiguator `{}`", prefix), 0..idx)),
             };
             Ok(Some((d, &rest[1..])))
         } else {
@@ -1994,12 +2018,7 @@ fn disambiguator_error(
     link_range: Range<usize>,
     msg: &str,
 ) {
-    report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, item, dox, &link_range, |diag, _sp| {
-        diag.note(
-            "the disambiguator is the part of the link before the `@` sign, \
-             or a suffix such as `()` for functions",
-        );
-    });
+    report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, item, dox, &link_range, |_diag, _sp| {});
 }
 
 /// Report an ambiguity error, where there were multiple possible resolutions.
diff --git a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr
index 9e7699eea9a..2904603dfc3 100644
--- a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr
+++ b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr
@@ -2,7 +2,7 @@ error: unknown disambiguator `foo`
   --> $DIR/unknown-disambiguator.rs:1:17
    |
 LL | //! Linking to [foo@banana] and [`bar@banana!()`].
-   |                 ^^^^^^^^^^
+   |                 ^^^
    |
 note: the lint level is defined here
   --> $DIR/unknown-disambiguator.rs:8:9
@@ -10,31 +10,24 @@ note: the lint level is defined here
 LL | #![deny(warnings)]
    |         ^^^^^^^^
    = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]`
-   = note: the disambiguator is the part of the link before the `@` sign, or a suffix such as `()` for functions
 
 error: unknown disambiguator `bar`
-  --> $DIR/unknown-disambiguator.rs:1:34
+  --> $DIR/unknown-disambiguator.rs:1:35
    |
 LL | //! Linking to [foo@banana] and [`bar@banana!()`].
-   |                                  ^^^^^^^^^^^^^^^
-   |
-   = note: the disambiguator is the part of the link before the `@` sign, or a suffix such as `()` for functions
+   |                                   ^^^
 
 error: unknown disambiguator ``
   --> $DIR/unknown-disambiguator.rs:4:31
    |
 LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()).
-   |                               ^^^^^^^^^^
-   |
-   = note: the disambiguator is the part of the link before the `@` sign, or a suffix such as `()` for functions
+   |                               ^
 
 error: unknown disambiguator ``
   --> $DIR/unknown-disambiguator.rs:4:57
    |
 LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()).
-   |                                                         ^^^^^^^^^^^
-   |
-   = note: the disambiguator is the part of the link before the `@` sign, or a suffix such as `()` for functions
+   |                                                         ^
 
 error: aborting due to 4 previous errors