Skip to content

Commit 56347a1

Browse files
committed
Point to disambiguator instead of whole link
And, now that we do that, we can remove the explanatory note since the error span should make it clear what the disambiguator is.
1 parent 4572e7f commit 56347a1

File tree

3 files changed

+35
-22
lines changed

3 files changed

+35
-22
lines changed

src/librustdoc/html/markdown.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1162,6 +1162,7 @@ crate fn plain_text_summary(md: &str) -> String {
11621162
s
11631163
}
11641164

1165+
#[derive(Debug)]
11651166
crate struct MarkdownLink {
11661167
pub kind: LinkType,
11671168
pub link: String,

src/librustdoc/passes/collect_intra_doc_links.rs

+29-10
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,7 @@ impl LinkCollector<'_, '_> {
950950
}
951951

952952
let link = ori_link.link.replace("`", "");
953+
let no_backticks_range = range_between_backticks(&ori_link);
953954
let parts = link.split('#').collect::<Vec<_>>();
954955
let (link, extra_fragment) = if parts.len() > 2 {
955956
// A valid link can't have multiple #'s
@@ -976,8 +977,10 @@ impl LinkCollector<'_, '_> {
976977
let (mut path_str, disambiguator) = match Disambiguator::from_str(&link) {
977978
Ok(Some((d, path))) => (path.trim(), Some(d)),
978979
Ok(None) => (link.trim(), None),
979-
Err(err_msg) => {
980-
disambiguator_error(self.cx, &item, dox, ori_link.range, &err_msg);
980+
Err((err_msg, relative_range)) => {
981+
let disambiguator_range = (no_backticks_range.start + relative_range.start)
982+
..(no_backticks_range.start + relative_range.end);
983+
disambiguator_error(self.cx, &item, dox, disambiguator_range, &err_msg);
981984
return None;
982985
}
983986
};
@@ -1491,6 +1494,27 @@ impl LinkCollector<'_, '_> {
14911494
}
14921495
}
14931496

1497+
/// Get the section of a link between the backticks,
1498+
/// or the whole link if there aren't any backticks.
1499+
///
1500+
/// For example:
1501+
///
1502+
/// ```text
1503+
/// [`Foo`]
1504+
/// ^^^
1505+
/// ```
1506+
fn range_between_backticks(ori_link: &MarkdownLink) -> Range<usize> {
1507+
let after_first_backtick_group = ori_link.link.bytes().position(|b| b != b'`').unwrap_or(0);
1508+
let before_second_backtick_group = ori_link
1509+
.link
1510+
.bytes()
1511+
.skip(after_first_backtick_group)
1512+
.position(|b| b == b'`')
1513+
.unwrap_or(ori_link.link.len());
1514+
(ori_link.range.start + after_first_backtick_group)
1515+
..(ori_link.range.start + before_second_backtick_group)
1516+
}
1517+
14941518
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
14951519
/// Disambiguators for a link.
14961520
enum Disambiguator {
@@ -1522,7 +1546,7 @@ impl Disambiguator {
15221546
/// This returns `Ok(Some(...))` if a disambiguator was found,
15231547
/// `Ok(None)` if no disambiguator was found, or `Err(...)`
15241548
/// if there was a problem with the disambiguator.
1525-
fn from_str(link: &str) -> Result<Option<(Self, &str)>, String> {
1549+
fn from_str(link: &str) -> Result<Option<(Self, &str)>, (String, Range<usize>)> {
15261550
use Disambiguator::{Kind, Namespace as NS, Primitive};
15271551

15281552
let find_suffix = || {
@@ -1558,7 +1582,7 @@ impl Disambiguator {
15581582
"value" => NS(Namespace::ValueNS),
15591583
"macro" => NS(Namespace::MacroNS),
15601584
"prim" | "primitive" => Primitive,
1561-
_ => return Err(format!("unknown disambiguator `{}`", prefix)),
1585+
_ => return Err((format!("unknown disambiguator `{}`", prefix), 0..idx)),
15621586
};
15631587
Ok(Some((d, &rest[1..])))
15641588
} else {
@@ -1994,12 +2018,7 @@ fn disambiguator_error(
19942018
link_range: Range<usize>,
19952019
msg: &str,
19962020
) {
1997-
report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, item, dox, &link_range, |diag, _sp| {
1998-
diag.note(
1999-
"the disambiguator is the part of the link before the `@` sign, \
2000-
or a suffix such as `()` for functions",
2001-
);
2002-
});
2021+
report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, item, dox, &link_range, |_diag, _sp| {});
20032022
}
20042023

20052024
/// Report an ambiguity error, where there were multiple possible resolutions.

src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr

+5-12
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,32 @@ error: unknown disambiguator `foo`
22
--> $DIR/unknown-disambiguator.rs:1:17
33
|
44
LL | //! Linking to [foo@banana] and [`bar@banana!()`].
5-
| ^^^^^^^^^^
5+
| ^^^
66
|
77
note: the lint level is defined here
88
--> $DIR/unknown-disambiguator.rs:8:9
99
|
1010
LL | #![deny(warnings)]
1111
| ^^^^^^^^
1212
= note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]`
13-
= note: the disambiguator is the part of the link before the `@` sign, or a suffix such as `()` for functions
1413

1514
error: unknown disambiguator `bar`
16-
--> $DIR/unknown-disambiguator.rs:1:34
15+
--> $DIR/unknown-disambiguator.rs:1:35
1716
|
1817
LL | //! Linking to [foo@banana] and [`bar@banana!()`].
19-
| ^^^^^^^^^^^^^^^
20-
|
21-
= note: the disambiguator is the part of the link before the `@` sign, or a suffix such as `()` for functions
18+
| ^^^
2219

2320
error: unknown disambiguator ``
2421
--> $DIR/unknown-disambiguator.rs:4:31
2522
|
2623
LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()).
27-
| ^^^^^^^^^^
28-
|
29-
= note: the disambiguator is the part of the link before the `@` sign, or a suffix such as `()` for functions
24+
| ^
3025

3126
error: unknown disambiguator ``
3227
--> $DIR/unknown-disambiguator.rs:4:57
3328
|
3429
LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()).
35-
| ^^^^^^^^^^^
36-
|
37-
= note: the disambiguator is the part of the link before the `@` sign, or a suffix such as `()` for functions
30+
| ^
3831

3932
error: aborting due to 4 previous errors
4033

0 commit comments

Comments
 (0)