Skip to content

Commit

Permalink
When unable to sinthesize link span, fallback to previous behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Jun 6, 2018
1 parent 507dfd2 commit 7d0b6b7
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 35 deletions.
55 changes: 35 additions & 20 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1194,9 +1194,6 @@ fn resolution_failure(
let msg = format!("`[{}]` cannot be resolved, ignoring it...", path_str);

let code_dox = sp.to_src(cx);
// The whitespace before the `///` to properly find the original span location.
let dox_leading_whitespace = code_dox.lines().nth(1)
.map(|x| x.len() - x.trim_left().len()).unwrap_or(0);

let doc_comment_padding = 3;
let mut diag = if let Some(link_range) = link_range {
Expand All @@ -1205,26 +1202,44 @@ fn resolution_failure(
// | link_range
// last_new_line_offset

let line_offset = dox[..link_range.start].lines().count();
let code_dox_len = if line_offset <= 1 {
let mut diag;
if dox.lines().count() == code_dox.lines().count() {
let line_offset = dox[..link_range.start].lines().count();
// The span starts in the `///`, so we don't have to account for the leading whitespace
doc_comment_padding
} else {
// The first `///`
doc_comment_padding +
// Each subsequent leading whitespace and `///`
(doc_comment_padding + dox_leading_whitespace)
// The line position inside the doc string
* (line_offset - 1)
};
let code_dox_len = if line_offset <= 1 {
doc_comment_padding
} else {
// The first `///`
doc_comment_padding +
// Each subsequent leading whitespace and `///`
code_dox.lines().skip(1).take(line_offset - 1).fold(0, |sum, line| {
sum + doc_comment_padding + line.len() - line.trim().len()
})
};

// Extract the specific span
let lo = sp.lo() + syntax_pos::BytePos((link_range.start + code_dox_len) as u32);
let hi = lo + syntax_pos::BytePos(link_range.len() as u32);
let sp = sp.with_lo(lo).with_hi(hi);
// Extract the specific span
let lo = sp.lo() + syntax_pos::BytePos((link_range.start + code_dox_len) as u32);
let hi = lo + syntax_pos::BytePos(link_range.len() as u32);
let sp = sp.with_lo(lo).with_hi(hi);

let mut diag = cx.sess().struct_span_warn(sp, &msg);
diag.span_label(sp, "cannot be resolved, ignoring");
diag = cx.sess().struct_span_warn(sp, &msg);
diag.span_label(sp, "cannot be resolved, ignoring");
} else {
diag = cx.sess().struct_span_warn(sp, &msg);

let last_new_line_offset = dox[..link_range.start].rfind('\n').map_or(0, |n| n + 1);
let line = dox[last_new_line_offset..].lines().next().unwrap_or("");

// Print the line containing the `link_range` and manually mark it with '^'s
diag.note(&format!(
"the link appears in this line:\n\n{line}\n\
{indicator: <before$}{indicator:^<found$}",
line=line,
indicator="",
before=link_range.start - last_new_line_offset,
found=link_range.len(),
));
}
diag
} else {
cx.sess().struct_span_warn(sp, &msg)
Expand Down
42 changes: 39 additions & 3 deletions src/test/rustdoc-ui/intra-links-warning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,47 @@
// compile-pass

//! Test with [Foo::baz], [Bar::foo], ...
//! , [Uniooon::X] and [Qux::Z].
//! .
//! , [Uniooon::X] and [Qux::Z].
//! , [Uniooon::X] and [Qux::Z].
//!
//! , [Uniooon::X] and [Qux::Z].
/// [Qux:Y]
pub struct Foo {
pub bar: usize,
}

/// Foo
/// bar [BarA] bar
/// baz
pub fn a() {}

/**
* Foo
* bar [BarB] bar
* baz
*/
pub fn b() {}

/** Foo
bar [BarC] bar
baz
let bar_c_1 = 0;
let bar_c_2 = 0;
let g = [bar_c_1];
let h = g[bar_c_2];
*/
pub fn c() {}

#[doc = "Foo\nbar [BarD] bar\nbaz"]
pub fn d() {}

macro_rules! f {
($f:expr) => {
#[doc = $f]
pub fn f() {}
}
}
f!("Foo\nbar [BarF] bar\nbaz");
87 changes: 75 additions & 12 deletions src/test/rustdoc-ui/intra-links-warning.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,95 @@ warning: `[Bar::foo]` cannot be resolved, ignoring it...
| ^^^^^^^^ cannot be resolved, ignoring

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

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

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

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

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

warning: `[BarA]` cannot be resolved, ignoring it...
--> $DIR/intra-links-warning.rs:24:10
|
24 | /// bar [BarA] bar
| ^^^^ cannot be resolved, ignoring

warning: `[BarB]` cannot be resolved, ignoring it...
--> $DIR/intra-links-warning.rs:28:1
|
28 | / /**
29 | | * Foo
30 | | * bar [BarB] bar
31 | | * baz
32 | | */
| |___^
|
= note: the link appears in this line:

bar [BarB] bar
^^^^

warning: `[BarC]` cannot be resolved, ignoring it...
--> $DIR/intra-links-warning.rs:35:1
|
35 | / /** Foo
36 | |
37 | | bar [BarC] bar
38 | | baz
... |
44 | |
45 | | */
| |__^
|
= note: the link appears in this line:

bar [BarC] bar
^^^^

warning: `[BarD]` cannot be resolved, ignoring it...
--> $DIR/intra-links-warning.rs:48:1
|
48 | #[doc = "Foo/nbar [BarD] bar/nbaz"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the link appears in this line:

bar [BarD] bar
^^^^

warning: `[BarF]` cannot be resolved, ignoring it...
--> $DIR/intra-links-warning.rs:53:9
|
53 | #[doc = $f]
| ^^^^^^^^^^^
...
57 | f!("Foo/nbar [BarF] bar/nbaz");
| ------------------------------- in this macro invocation
|
= note: the link appears in this line:

bar [BarF] bar
^^^^

0 comments on commit 7d0b6b7

Please sign in to comment.