Skip to content

Commit 06b18db

Browse files
authored
Rollup merge of rust-lang#148735 - chenyukang:yukang-fix-ice-148732, r=nnethercote
Fix ICE caused by invalid spans for shrink_file Fixes rust-lang#148732 There are two issues in this function: 1. the original issue is caused by a typo error, which is fixed in the first commit 2. another different ice(Patch span `7..7` is beyond the end of buffer `0`) will be reported after fixing the first one, is caused by spans cross file boundaries due to macro expansion. It is fixed in the second commit. r? `@nnethercote` edited: also fixes rust-lang#148684, added a new testcase for it in the last commit.
2 parents c3171d1 + 4a2c9a1 commit 06b18db

File tree

5 files changed

+92
-14
lines changed

5 files changed

+92
-14
lines changed

compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -350,22 +350,27 @@ impl AnnotateSnippetEmitter {
350350
"all spans must be disjoint",
351351
);
352352

353+
let lo = subst.parts.iter().map(|part| part.span.lo()).min()?;
354+
let lo_file = sm.lookup_source_file(lo);
355+
let hi = subst.parts.iter().map(|part| part.span.hi()).max()?;
356+
let hi_file = sm.lookup_source_file(hi);
357+
358+
// The different spans might belong to different contexts, if so ignore suggestion.
359+
if lo_file.stable_id != hi_file.stable_id {
360+
return None;
361+
}
362+
363+
// We can't splice anything if the source is unavailable.
364+
if !sm.ensure_source_file_source_present(&lo_file) {
365+
return None;
366+
}
367+
353368
// Account for cases where we are suggesting the same code that's already
354369
// there. This shouldn't happen often, but in some cases for multipart
355370
// suggestions it's much easier to handle it here than in the origin.
356371
subst.parts.retain(|p| is_different(sm, &p.snippet, p.span));
357372

358-
let item_span = subst.parts.first()?;
359-
let file = sm.lookup_source_file(item_span.span.lo());
360-
if should_show_source_code(
361-
&self.ignored_directories_in_source_blocks,
362-
sm,
363-
&file,
364-
) {
365-
Some(subst)
366-
} else {
367-
None
368-
}
373+
if subst.parts.is_empty() { None } else { Some(subst) }
369374
})
370375
.collect::<Vec<_>>();
371376

@@ -745,14 +750,20 @@ fn shrink_file(
745750
) -> Option<(Span, String, usize)> {
746751
let lo_byte = spans.iter().map(|s| s.lo()).min()?;
747752
let lo_loc = sm.lookup_char_pos(lo_byte);
748-
let lo = lo_loc.file.line_bounds(lo_loc.line.saturating_sub(1)).start;
749753

750754
let hi_byte = spans.iter().map(|s| s.hi()).max()?;
751755
let hi_loc = sm.lookup_char_pos(hi_byte);
752-
let hi = lo_loc.file.line_bounds(hi_loc.line.saturating_sub(1)).end;
756+
757+
if lo_loc.file.stable_id != hi_loc.file.stable_id {
758+
// this may happen when spans cross file boundaries due to macro expansion.
759+
return None;
760+
}
761+
762+
let lo = lo_loc.file.line_bounds(lo_loc.line.saturating_sub(1)).start;
763+
let hi = hi_loc.file.line_bounds(hi_loc.line.saturating_sub(1)).end;
753764

754765
let bounding_span = Span::with_root_ctxt(lo, hi);
755-
let source = sm.span_to_snippet(bounding_span).unwrap_or_default();
766+
let source = sm.span_to_snippet(bounding_span).ok()?;
756767
let offset_line = sm.doctest_offset_line(file_name, lo_loc.line);
757768

758769
Some((bounding_span, source, offset_line))
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
reuse a as b {
2+
//~^ ERROR cannot find function `a` in this scope
3+
//~| ERROR functions delegation is not yet fully implemented
4+
dbg!(b);
5+
//~^ ERROR missing lifetime specifier
6+
}
7+
8+
fn main() {}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
error[E0106]: missing lifetime specifier
2+
--> $DIR/ice-line-bounds-issue-148732.rs:4:5
3+
|
4+
LL | dbg!(b);
5+
| ^^^^^^^ expected named lifetime parameter
6+
|
7+
= note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
8+
|
9+
10+
error[E0425]: cannot find function `a` in this scope
11+
--> $DIR/ice-line-bounds-issue-148732.rs:1:7
12+
|
13+
LL | reuse a as b {
14+
| ^ not found in this scope
15+
16+
error[E0658]: functions delegation is not yet fully implemented
17+
--> $DIR/ice-line-bounds-issue-148732.rs:1:1
18+
|
19+
LL | / reuse a as b {
20+
LL | |
21+
LL | |
22+
LL | | dbg!(b);
23+
LL | |
24+
LL | | }
25+
| |_^
26+
|
27+
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
28+
= help: add `#![feature(fn_delegation)]` to the crate attributes to enable
29+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
30+
31+
error: aborting due to 3 previous errors
32+
33+
Some errors have detailed explanations: E0106, E0425, E0658.
34+
For more information about an error, try `rustc --explain E0106`.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
struct A {
2+
b: Vec<u8>,
3+
c: usize,
4+
}
5+
6+
fn main() {
7+
A(2, vec![])
8+
//~^ ERROR expected function, tuple struct or tuple variant, found struct `A`
9+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0423]: expected function, tuple struct or tuple variant, found struct `A`
2+
--> $DIR/ice-line-bounds-issue-148684.rs:7:5
3+
|
4+
LL | / struct A {
5+
LL | | b: Vec<u8>,
6+
LL | | c: usize,
7+
LL | | }
8+
| |_- `A` defined here
9+
...
10+
LL | A(2, vec![])
11+
| ^^^^^^^^^^^^
12+
|
13+
14+
error: aborting due to 1 previous error
15+
16+
For more information about this error, try `rustc --explain E0423`.

0 commit comments

Comments
 (0)