Skip to content

Commit fd65e25

Browse files
committed
Rollup merge of #55962 - QuietMisdreavus:tricky-spans, r=GuillaumeGomez
rustdoc: properly calculate spans for intra-doc link resolution errors Fixes #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...)
2 parents 357031a + aa3d7a4 commit fd65e25

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

Diff for: src/librustdoc/passes/collect_intra_doc_links.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ fn resolution_failure(
527527
doc_comment_padding +
528528
// Each subsequent leading whitespace and `///`
529529
code_dox.lines().skip(1).take(line_offset - 1).fold(0, |sum, line| {
530-
sum + doc_comment_padding + line.len() - line.trim().len()
530+
sum + doc_comment_padding + line.len() - line.trim_start().len()
531531
})
532532
};
533533

Diff for: src/test/rustdoc-ui/intra-link-span-ice-55723.rs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// ignore-tidy-end-whitespace
12+
13+
#![deny(intra_doc_link_resolution_failure)]
14+
15+
// An error in calculating spans while reporting intra-doc link resolution errors caused rustdoc to
16+
// attempt to slice in the middle of a multibyte character. See
17+
// https://github.com/rust-lang/rust/issues/55723
18+
19+
/// ## For example:
20+
///
21+
/// (arr[i])
22+
pub fn test_ice() {
23+
unimplemented!();
24+
}

Diff for: src/test/rustdoc-ui/intra-link-span-ice-55723.stderr

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error: `[i]` cannot be resolved, ignoring it...
2+
--> $DIR/intra-link-span-ice-55723.rs:21:10
3+
|
4+
LL | /// (arr[i])
5+
| ^ cannot be resolved, ignoring
6+
|
7+
note: lint level defined here
8+
--> $DIR/intra-link-span-ice-55723.rs:13:9
9+
|
10+
LL | #![deny(intra_doc_link_resolution_failure)]
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
= help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
13+

0 commit comments

Comments
 (0)