From 507dfd2148f68bc3bd6349d5e666b12e360a9d15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 6 Jun 2018 00:30:25 -0700 Subject: [PATCH 1/3] Use spans pointing at the inside of a rustdoc attribute --- src/librustdoc/clean/mod.rs | 46 +++++++++----- src/test/rustdoc-ui/intra-links-warning.rs | 8 ++- .../rustdoc-ui/intra-links-warning.stderr | 63 ++++++++++--------- 3 files changed, 68 insertions(+), 49 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1c1ba208678ed..8055c99ceb839 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1191,30 +1191,44 @@ fn resolution_failure( link_range: Option>, ) { let sp = span_of_attrs(attrs); - let mut diag = cx.sess() - .struct_span_warn(sp, &format!("[{}] cannot be resolved, ignoring it...", path_str)); + let msg = format!("`[{}]` cannot be resolved, ignoring it...", path_str); - if let Some(link_range) = link_range { + 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 { // blah blah blah\nblah\nblah [blah] blah blah\nblah blah // ^ ~~~~~~ // | link_range // last_new_line_offset - 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: $DIR/intra-links-warning.rs:13:1 +warning: `[Foo::baz]` cannot be resolved, ignoring it... + --> $DIR/intra-links-warning.rs:13:23 | -13 | / //! Test with [Foo::baz], [Bar::foo], ... -14 | | //! -15 | | //! and [Uniooon::X]. - | |_____________________^ +13 | //! Test with [Foo::baz], [Bar::foo], ... + | ^^^^^^^^ cannot be resolved, ignoring + +warning: `[Bar::foo]` cannot be resolved, ignoring it... + --> $DIR/intra-links-warning.rs:13:35 | - = note: the link appears in this line: - - Test with [Foo::baz], [Bar::foo], ... - ^^^^^^^^ +13 | //! Test with [Foo::baz], [Bar::foo], ... + | ^^^^^^^^ cannot be resolved, ignoring -warning: [Bar::foo] cannot be resolved, ignoring it... - --> $DIR/intra-links-warning.rs:13:1 +warning: `[Uniooon::X]` cannot be resolved, ignoring it... + --> $DIR/intra-links-warning.rs:14:15 | -13 | / //! Test with [Foo::baz], [Bar::foo], ... -14 | | //! -15 | | //! and [Uniooon::X]. - | |_____________________^ +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 | - = note: the link appears in this line: - - Test with [Foo::baz], [Bar::foo], ... - ^^^^^^^^ +14 | //! , [Uniooon::X] and [Qux::Z]. + | ^^^^^^ cannot be resolved, ignoring -warning: [Uniooon::X] cannot be resolved, ignoring it... - --> $DIR/intra-links-warning.rs:13:1 +warning: `[Uniooon::X]` cannot be resolved, ignoring it... + --> $DIR/intra-links-warning.rs:16:15 | -13 | / //! Test with [Foo::baz], [Bar::foo], ... -14 | | //! -15 | | //! and [Uniooon::X]. - | |_____________________^ +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 + | +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 | - = note: the link appears in this line: - - and [Uniooon::X]. - ^^^^^^^^^^ +18 | /// [Qux:Y] + | ^^^^^ cannot be resolved, ignoring From 7d0b6b75f05a669ee8cc76e651a654296d7d166c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 6 Jun 2018 09:14:09 -0700 Subject: [PATCH 2/3] When unable to sinthesize link span, fallback to previous behavior --- src/librustdoc/clean/mod.rs | 55 +++++++----- src/test/rustdoc-ui/intra-links-warning.rs | 42 ++++++++- .../rustdoc-ui/intra-links-warning.stderr | 87 ++++++++++++++++--- 3 files changed, 149 insertions(+), 35 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 8055c99ceb839..226b3627e3e08 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -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 { @@ -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: { + #[doc = $f] + pub fn f() {} + } +} +f!("Foo\nbar [BarF] bar\nbaz"); diff --git a/src/test/rustdoc-ui/intra-links-warning.stderr b/src/test/rustdoc-ui/intra-links-warning.stderr index a5a5598ed8fc8..52adba5679fe0 100644 --- a/src/test/rustdoc-ui/intra-links-warning.stderr +++ b/src/test/rustdoc-ui/intra-links-warning.stderr @@ -11,28 +11,28 @@ 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 @@ -40,3 +40,66 @@ warning: `[Qux:Y]` cannot be resolved, ignoring it... 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 + ^^^^ + From 31bb50b6b949aa19fc6d5ed76a4d458e8a5af8a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 7 Jun 2018 09:47:09 -0700 Subject: [PATCH 3/3] Use `from_inner_byte_pos` for cleaner code --- src/librustdoc/clean/mod.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 226b3627e3e08..e24c1a23b89b0 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1218,9 +1218,10 @@ fn resolution_failure( }; // 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 sp = sp.from_inner_byte_pos( + link_range.start + code_dox_len, + link_range.end + code_dox_len, + ); diag = cx.sess().struct_span_warn(sp, &msg); diag.span_label(sp, "cannot be resolved, ignoring");