Skip to content

Commit

Permalink
Point to disambiguator instead of whole link
Browse files Browse the repository at this point in the history
And, now that we do that, we can remove the explanatory note since the
error span should make it clear what the disambiguator is.
  • Loading branch information
camelid committed Mar 29, 2021
1 parent 4572e7f commit 56347a1
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 22 deletions.
1 change: 1 addition & 0 deletions src/librustdoc/html/markdown.rs
Expand Up @@ -1162,6 +1162,7 @@ crate fn plain_text_summary(md: &str) -> String {
s
}

#[derive(Debug)]
crate struct MarkdownLink {
pub kind: LinkType,
pub link: String,
Expand Down
39 changes: 29 additions & 10 deletions src/librustdoc/passes/collect_intra_doc_links.rs
Expand Up @@ -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
Expand All @@ -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;
}
};
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 = || {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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.
Expand Down
17 changes: 5 additions & 12 deletions src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr
Expand Up @@ -2,39 +2,32 @@ 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
|
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

0 comments on commit 56347a1

Please sign in to comment.