Skip to content

Commit 507dfd2

Browse files
committed
Use spans pointing at the inside of a rustdoc attribute
1 parent 41affd0 commit 507dfd2

File tree

3 files changed

+68
-49
lines changed

3 files changed

+68
-49
lines changed

src/librustdoc/clean/mod.rs

+30-16
Original file line numberDiff line numberDiff line change
@@ -1191,30 +1191,44 @@ fn resolution_failure(
11911191
link_range: Option<Range<usize>>,
11921192
) {
11931193
let sp = span_of_attrs(attrs);
1194-
let mut diag = cx.sess()
1195-
.struct_span_warn(sp, &format!("[{}] cannot be resolved, ignoring it...", path_str));
1194+
let msg = format!("`[{}]` cannot be resolved, ignoring it...", path_str);
11961195

1197-
if let Some(link_range) = link_range {
1196+
let code_dox = sp.to_src(cx);
1197+
// The whitespace before the `///` to properly find the original span location.
1198+
let dox_leading_whitespace = code_dox.lines().nth(1)
1199+
.map(|x| x.len() - x.trim_left().len()).unwrap_or(0);
1200+
1201+
let doc_comment_padding = 3;
1202+
let mut diag = if let Some(link_range) = link_range {
11981203
// blah blah blah\nblah\nblah [blah] blah blah\nblah blah
11991204
// ^ ~~~~~~
12001205
// | link_range
12011206
// last_new_line_offset
12021207

1203-
let last_new_line_offset = dox[..link_range.start].rfind('\n').map_or(0, |n| n + 1);
1204-
let line = dox[last_new_line_offset..].lines().next().unwrap_or("");
1205-
1206-
// Print the line containing the `link_range` and manually mark it with '^'s
1207-
diag.note(&format!(
1208-
"the link appears in this line:\n\n{line}\n{indicator: <before$}{indicator:^<found$}",
1209-
line=line,
1210-
indicator="",
1211-
before=link_range.start - last_new_line_offset,
1212-
found=link_range.len(),
1213-
));
1214-
} else {
1208+
let line_offset = dox[..link_range.start].lines().count();
1209+
let code_dox_len = if line_offset <= 1 {
1210+
// The span starts in the `///`, so we don't have to account for the leading whitespace
1211+
doc_comment_padding
1212+
} else {
1213+
// The first `///`
1214+
doc_comment_padding +
1215+
// Each subsequent leading whitespace and `///`
1216+
(doc_comment_padding + dox_leading_whitespace)
1217+
// The line position inside the doc string
1218+
* (line_offset - 1)
1219+
};
12151220

1216-
}
1221+
// Extract the specific span
1222+
let lo = sp.lo() + syntax_pos::BytePos((link_range.start + code_dox_len) as u32);
1223+
let hi = lo + syntax_pos::BytePos(link_range.len() as u32);
1224+
let sp = sp.with_lo(lo).with_hi(hi);
12171225

1226+
let mut diag = cx.sess().struct_span_warn(sp, &msg);
1227+
diag.span_label(sp, "cannot be resolved, ignoring");
1228+
diag
1229+
} else {
1230+
cx.sess().struct_span_warn(sp, &msg)
1231+
};
12181232
diag.emit();
12191233
}
12201234

src/test/rustdoc-ui/intra-links-warning.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010

1111
// compile-pass
1212

13-
//! Test with [Foo::baz], [Bar::foo], ...
14-
//!
15-
//! and [Uniooon::X].
13+
//! Test with [Foo::baz], [Bar::foo], ...
14+
//! , [Uniooon::X] and [Qux::Z].
15+
//! .
16+
//! , [Uniooon::X] and [Qux::Z].
1617
18+
/// [Qux:Y]
1719
pub struct Foo {
1820
pub bar: usize,
1921
}
+33-30
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,42 @@
1-
warning: [Foo::baz] cannot be resolved, ignoring it...
2-
--> $DIR/intra-links-warning.rs:13:1
1+
warning: `[Foo::baz]` cannot be resolved, ignoring it...
2+
--> $DIR/intra-links-warning.rs:13:23
33
|
4-
13 | / //! Test with [Foo::baz], [Bar::foo], ...
5-
14 | | //!
6-
15 | | //! and [Uniooon::X].
7-
| |_____________________^
4+
13 | //! Test with [Foo::baz], [Bar::foo], ...
5+
| ^^^^^^^^ cannot be resolved, ignoring
6+
7+
warning: `[Bar::foo]` cannot be resolved, ignoring it...
8+
--> $DIR/intra-links-warning.rs:13:35
89
|
9-
= note: the link appears in this line:
10-
11-
Test with [Foo::baz], [Bar::foo], ...
12-
^^^^^^^^
10+
13 | //! Test with [Foo::baz], [Bar::foo], ...
11+
| ^^^^^^^^ cannot be resolved, ignoring
1312

14-
warning: [Bar::foo] cannot be resolved, ignoring it...
15-
--> $DIR/intra-links-warning.rs:13:1
13+
warning: `[Uniooon::X]` cannot be resolved, ignoring it...
14+
--> $DIR/intra-links-warning.rs:14:15
1615
|
17-
13 | / //! Test with [Foo::baz], [Bar::foo], ...
18-
14 | | //!
19-
15 | | //! and [Uniooon::X].
20-
| |_____________________^
16+
14 | //! , [Uniooon::X] and [Qux::Z].
17+
| ^^^^^^^^^^ cannot be resolved, ignoring
18+
19+
warning: `[Qux::Z]` cannot be resolved, ignoring it...
20+
--> $DIR/intra-links-warning.rs:14:32
2121
|
22-
= note: the link appears in this line:
23-
24-
Test with [Foo::baz], [Bar::foo], ...
25-
^^^^^^^^
22+
14 | //! , [Uniooon::X] and [Qux::Z].
23+
| ^^^^^^ cannot be resolved, ignoring
2624

27-
warning: [Uniooon::X] cannot be resolved, ignoring it...
28-
--> $DIR/intra-links-warning.rs:13:1
25+
warning: `[Uniooon::X]` cannot be resolved, ignoring it...
26+
--> $DIR/intra-links-warning.rs:16:15
2927
|
30-
13 | / //! Test with [Foo::baz], [Bar::foo], ...
31-
14 | | //!
32-
15 | | //! and [Uniooon::X].
33-
| |_____________________^
28+
16 | //! , [Uniooon::X] and [Qux::Z].
29+
| ^^^^^^^^^^ cannot be resolved, ignoring
30+
31+
warning: `[Qux::Z]` cannot be resolved, ignoring it...
32+
--> $DIR/intra-links-warning.rs:16:32
33+
|
34+
16 | //! , [Uniooon::X] and [Qux::Z].
35+
| ^^^^^^ cannot be resolved, ignoring
36+
37+
warning: `[Qux:Y]` cannot be resolved, ignoring it...
38+
--> $DIR/intra-links-warning.rs:18:13
3439
|
35-
= note: the link appears in this line:
36-
37-
and [Uniooon::X].
38-
^^^^^^^^^^
40+
18 | /// [Qux:Y]
41+
| ^^^^^ cannot be resolved, ignoring
3942

0 commit comments

Comments
 (0)