Skip to content

Commit

Permalink
Rollup merge of rust-lang#55962 - QuietMisdreavus:tricky-spans, r=Gui…
Browse files Browse the repository at this point in the history
…llaumeGomez

rustdoc: properly calculate spans for intra-doc link resolution errors

Fixes rust-lang#55723

When rustdoc is reporting a resolution error for intra-doc links, it needs to convert a span from one relative to the *markdown* (as the links are only found on the final markdown text) to one relative to the *source code* (as the error reporting is meant to show where the line is in the source, so the user can fix it). However, a calculation for how much "offset" to apply had a subtle error: it trimmed the whole line when attempting to account for leading indentation. This caused it to add in *trailing* whitespace into this calculation, which created an incorrect span.

In a lot of situations, this isn't a problem - the span will be shifted in the code slightly, but the warning will still be displayed and mostly legible. However, there is one important situation where this can cause an ICE: multi-byte codepoints. If a shifted span now has a starting point in the middle of a multi-byte codepoint, libsyntax will panic when trying to track what source item it corresponds to. This flew under our radar because trailing whitespace and multi-byte codepoints are both situations that we don't run into in the compiler repo.

(There is one more situation where this can error, that will be much harder to fix: block-style doc comments. Lines in a block-style doc comment have a zero-or-more (usually one) character offset per line, causing this calculation to be way off. I'm punting that to another issue, though...)
  • Loading branch information
pietroalbini committed Nov 16, 2018
2 parents 357031a + aa3d7a4 commit fd65e25
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/librustdoc/passes/collect_intra_doc_links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ fn resolution_failure(
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()
sum + doc_comment_padding + line.len() - line.trim_start().len()
})
};

Expand Down
24 changes: 24 additions & 0 deletions src/test/rustdoc-ui/intra-link-span-ice-55723.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// ignore-tidy-end-whitespace

#![deny(intra_doc_link_resolution_failure)]

// An error in calculating spans while reporting intra-doc link resolution errors caused rustdoc to
// attempt to slice in the middle of a multibyte character. See
// https://github.com/rust-lang/rust/issues/55723

/// ## For example:
///
/// (arr[i])
pub fn test_ice() {
unimplemented!();
}
13 changes: 13 additions & 0 deletions src/test/rustdoc-ui/intra-link-span-ice-55723.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
error: `[i]` cannot be resolved, ignoring it...
--> $DIR/intra-link-span-ice-55723.rs:21:10
|
LL | /// (arr[i])
| ^ cannot be resolved, ignoring
|
note: lint level defined here
--> $DIR/intra-link-span-ice-55723.rs:13:9
|
LL | #![deny(intra_doc_link_resolution_failure)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`

0 comments on commit fd65e25

Please sign in to comment.