Skip to content

Commit 75b8c10

Browse files
committed
Rollup merge of #48522 - etaoins:fix-find-width-of-character-at-span-bounds-check, r=estebank
Fix find_width_of_character_at_span bounds check Commit 0bd9667 added bounds checking of our current target byte position to prevent infinite loops. Unfortunately it was comparing the file-relative `target` versus the global `file_start_pos` and `file_end_pos`. The result is failing to detect multibyte characters unless their file-relative offset fit within their global offset. This causes other parts of the compiler to generate spans pointing to the middle of a multibyte character which will ultimately panic in `bytepos_to_file_charpos`. Fix by comparing the `target` to the total file size when moving forward and doing checked subtraction when moving backwards. This should preserve the intent of the bounds check while removing the offset confusion. cc @davidtwco Fixes #48508
2 parents 38f4d55 + 363d604 commit 75b8c10

File tree

3 files changed

+55
-8
lines changed

3 files changed

+55
-8
lines changed

src/libsyntax/codemap.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -705,17 +705,20 @@ impl CodeMap {
705705
};
706706
debug!("find_width_of_character_at_span: snippet=`{:?}`", snippet);
707707

708-
let file_start_pos = local_begin.fm.start_pos.to_usize();
709-
let file_end_pos = local_begin.fm.end_pos.to_usize();
710-
debug!("find_width_of_character_at_span: file_start_pos=`{:?}` file_end_pos=`{:?}`",
711-
file_start_pos, file_end_pos);
712-
713708
let mut target = if forwards { end_index + 1 } else { end_index - 1 };
714709
debug!("find_width_of_character_at_span: initial target=`{:?}`", target);
715710

716-
while !snippet.is_char_boundary(target - start_index)
717-
&& target >= file_start_pos && target <= file_end_pos {
718-
target = if forwards { target + 1 } else { target - 1 };
711+
while !snippet.is_char_boundary(target - start_index) && target < source_len {
712+
target = if forwards {
713+
target + 1
714+
} else {
715+
match target.checked_sub(1) {
716+
Some(target) => target,
717+
None => {
718+
break;
719+
}
720+
}
721+
};
719722
debug!("find_width_of_character_at_span: target=`{:?}`", target);
720723
}
721724
debug!("find_width_of_character_at_span: final target=`{:?}`", target);

src/test/run-pass/issue-48508-aux.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
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-test Not a test. Used by issue-48508.rs
12+
13+
pub fn other() -> f64 {
14+
let µ = 1.0;
15+
µ
16+
}

src/test/run-pass/issue-48508.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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+
// Regression test for issue #48508:
12+
//
13+
// Confusion between global and local file offsets caused incorrect handling of multibyte character
14+
// spans when compiling multiple files. One visible effect was an ICE generating debug information
15+
// when a multibyte character is at the end of a scope. The problematic code is actually in
16+
// issue-48508-aux.rs
17+
18+
// compile-flags:-g
19+
// ignore-pretty issue #37195
20+
21+
#![feature(non_ascii_idents)]
22+
23+
#[path = "issue-48508-aux.rs"]
24+
mod other_file;
25+
26+
fn main() {
27+
other_file::other();
28+
}

0 commit comments

Comments
 (0)