Skip to content

Commit 7d0b6b7

Browse files
committed
When unable to sinthesize link span, fallback to previous behavior
1 parent 507dfd2 commit 7d0b6b7

File tree

3 files changed

+149
-35
lines changed

3 files changed

+149
-35
lines changed

src/librustdoc/clean/mod.rs

+35-20
Original file line numberDiff line numberDiff line change
@@ -1194,9 +1194,6 @@ fn resolution_failure(
11941194
let msg = format!("`[{}]` cannot be resolved, ignoring it...", path_str);
11951195

11961196
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);
12001197

12011198
let doc_comment_padding = 3;
12021199
let mut diag = if let Some(link_range) = link_range {
@@ -1205,26 +1202,44 @@ fn resolution_failure(
12051202
// | link_range
12061203
// last_new_line_offset
12071204

1208-
let line_offset = dox[..link_range.start].lines().count();
1209-
let code_dox_len = if line_offset <= 1 {
1205+
let mut diag;
1206+
if dox.lines().count() == code_dox.lines().count() {
1207+
let line_offset = dox[..link_range.start].lines().count();
12101208
// 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-
};
1209+
let code_dox_len = if line_offset <= 1 {
1210+
doc_comment_padding
1211+
} else {
1212+
// The first `///`
1213+
doc_comment_padding +
1214+
// Each subsequent leading whitespace and `///`
1215+
code_dox.lines().skip(1).take(line_offset - 1).fold(0, |sum, line| {
1216+
sum + doc_comment_padding + line.len() - line.trim().len()
1217+
})
1218+
};
12201219

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);
1220+
// Extract the specific span
1221+
let lo = sp.lo() + syntax_pos::BytePos((link_range.start + code_dox_len) as u32);
1222+
let hi = lo + syntax_pos::BytePos(link_range.len() as u32);
1223+
let sp = sp.with_lo(lo).with_hi(hi);
12251224

1226-
let mut diag = cx.sess().struct_span_warn(sp, &msg);
1227-
diag.span_label(sp, "cannot be resolved, ignoring");
1225+
diag = cx.sess().struct_span_warn(sp, &msg);
1226+
diag.span_label(sp, "cannot be resolved, ignoring");
1227+
} else {
1228+
diag = cx.sess().struct_span_warn(sp, &msg);
1229+
1230+
let last_new_line_offset = dox[..link_range.start].rfind('\n').map_or(0, |n| n + 1);
1231+
let line = dox[last_new_line_offset..].lines().next().unwrap_or("");
1232+
1233+
// Print the line containing the `link_range` and manually mark it with '^'s
1234+
diag.note(&format!(
1235+
"the link appears in this line:\n\n{line}\n\
1236+
{indicator: <before$}{indicator:^<found$}",
1237+
line=line,
1238+
indicator="",
1239+
before=link_range.start - last_new_line_offset,
1240+
found=link_range.len(),
1241+
));
1242+
}
12281243
diag
12291244
} else {
12301245
cx.sess().struct_span_warn(sp, &msg)

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

+39-3
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,47 @@
1111
// compile-pass
1212

1313
//! Test with [Foo::baz], [Bar::foo], ...
14-
//! , [Uniooon::X] and [Qux::Z].
15-
//! .
16-
//! , [Uniooon::X] and [Qux::Z].
14+
//! , [Uniooon::X] and [Qux::Z].
15+
//!
16+
//! , [Uniooon::X] and [Qux::Z].
1717
1818
/// [Qux:Y]
1919
pub struct Foo {
2020
pub bar: usize,
2121
}
22+
23+
/// Foo
24+
/// bar [BarA] bar
25+
/// baz
26+
pub fn a() {}
27+
28+
/**
29+
* Foo
30+
* bar [BarB] bar
31+
* baz
32+
*/
33+
pub fn b() {}
34+
35+
/** Foo
36+
37+
bar [BarC] bar
38+
baz
39+
40+
let bar_c_1 = 0;
41+
let bar_c_2 = 0;
42+
let g = [bar_c_1];
43+
let h = g[bar_c_2];
44+
45+
*/
46+
pub fn c() {}
47+
48+
#[doc = "Foo\nbar [BarD] bar\nbaz"]
49+
pub fn d() {}
50+
51+
macro_rules! f {
52+
($f:expr) => {
53+
#[doc = $f]
54+
pub fn f() {}
55+
}
56+
}
57+
f!("Foo\nbar [BarF] bar\nbaz");

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

+75-12
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,95 @@ warning: `[Bar::foo]` cannot be resolved, ignoring it...
1111
| ^^^^^^^^ cannot be resolved, ignoring
1212

1313
warning: `[Uniooon::X]` cannot be resolved, ignoring it...
14-
--> $DIR/intra-links-warning.rs:14:15
14+
--> $DIR/intra-links-warning.rs:14:13
1515
|
16-
14 | //! , [Uniooon::X] and [Qux::Z].
17-
| ^^^^^^^^^^ cannot be resolved, ignoring
16+
14 | //! , [Uniooon::X] and [Qux::Z].
17+
| ^^^^^^^^^^ cannot be resolved, ignoring
1818

1919
warning: `[Qux::Z]` cannot be resolved, ignoring it...
20-
--> $DIR/intra-links-warning.rs:14:32
20+
--> $DIR/intra-links-warning.rs:14:30
2121
|
22-
14 | //! , [Uniooon::X] and [Qux::Z].
23-
| ^^^^^^ cannot be resolved, ignoring
22+
14 | //! , [Uniooon::X] and [Qux::Z].
23+
| ^^^^^^ cannot be resolved, ignoring
2424

2525
warning: `[Uniooon::X]` cannot be resolved, ignoring it...
26-
--> $DIR/intra-links-warning.rs:16:15
26+
--> $DIR/intra-links-warning.rs:16:14
2727
|
28-
16 | //! , [Uniooon::X] and [Qux::Z].
29-
| ^^^^^^^^^^ cannot be resolved, ignoring
28+
16 | //! , [Uniooon::X] and [Qux::Z].
29+
| ^^^^^^^^^^ cannot be resolved, ignoring
3030

3131
warning: `[Qux::Z]` cannot be resolved, ignoring it...
32-
--> $DIR/intra-links-warning.rs:16:32
32+
--> $DIR/intra-links-warning.rs:16:31
3333
|
34-
16 | //! , [Uniooon::X] and [Qux::Z].
35-
| ^^^^^^ cannot be resolved, ignoring
34+
16 | //! , [Uniooon::X] and [Qux::Z].
35+
| ^^^^^^ cannot be resolved, ignoring
3636

3737
warning: `[Qux:Y]` cannot be resolved, ignoring it...
3838
--> $DIR/intra-links-warning.rs:18:13
3939
|
4040
18 | /// [Qux:Y]
4141
| ^^^^^ cannot be resolved, ignoring
4242

43+
warning: `[BarA]` cannot be resolved, ignoring it...
44+
--> $DIR/intra-links-warning.rs:24:10
45+
|
46+
24 | /// bar [BarA] bar
47+
| ^^^^ cannot be resolved, ignoring
48+
49+
warning: `[BarB]` cannot be resolved, ignoring it...
50+
--> $DIR/intra-links-warning.rs:28:1
51+
|
52+
28 | / /**
53+
29 | | * Foo
54+
30 | | * bar [BarB] bar
55+
31 | | * baz
56+
32 | | */
57+
| |___^
58+
|
59+
= note: the link appears in this line:
60+
61+
bar [BarB] bar
62+
^^^^
63+
64+
warning: `[BarC]` cannot be resolved, ignoring it...
65+
--> $DIR/intra-links-warning.rs:35:1
66+
|
67+
35 | / /** Foo
68+
36 | |
69+
37 | | bar [BarC] bar
70+
38 | | baz
71+
... |
72+
44 | |
73+
45 | | */
74+
| |__^
75+
|
76+
= note: the link appears in this line:
77+
78+
bar [BarC] bar
79+
^^^^
80+
81+
warning: `[BarD]` cannot be resolved, ignoring it...
82+
--> $DIR/intra-links-warning.rs:48:1
83+
|
84+
48 | #[doc = "Foo/nbar [BarD] bar/nbaz"]
85+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
86+
|
87+
= note: the link appears in this line:
88+
89+
bar [BarD] bar
90+
^^^^
91+
92+
warning: `[BarF]` cannot be resolved, ignoring it...
93+
--> $DIR/intra-links-warning.rs:53:9
94+
|
95+
53 | #[doc = $f]
96+
| ^^^^^^^^^^^
97+
...
98+
57 | f!("Foo/nbar [BarF] bar/nbaz");
99+
| ------------------------------- in this macro invocation
100+
|
101+
= note: the link appears in this line:
102+
103+
bar [BarF] bar
104+
^^^^
105+

0 commit comments

Comments
 (0)