Auto merge of #25013 - pnkfelix:span_to_lines-oflo, r=huonw
Guard against overflow in `codemap::span_to_lines`. (Revised/expanded version of PR #24976) Make `span_to_lines` to return a `Result`. In `diagnostic`, catch `Err` from `span_to_lines` and print `"(unprintable span)"` instead. ---- There a number of recent issues that report the bug here. See e.g. #24761 and #24954. This change *might* fix them. However, that is *not* its main goal. The main goals are: 1. Make it possible for callers to recover from an error here, and 2. Insert a more conservative check, in that we are also checking that the files match up. ---- As a drive-by, fix #24997 , which was causing my attempts to `make check-stage1` on an `--enable-debug` build to fail.
This commit is contained in:
@@ -663,9 +663,22 @@ impl CodeMap {
|
||||
self.lookup_char_pos(sp.lo).file.name.to_string()
|
||||
}
|
||||
|
||||
pub fn span_to_lines(&self, sp: Span) -> FileLines {
|
||||
pub fn span_to_lines(&self, sp: Span) -> FileLinesResult {
|
||||
if sp.lo > sp.hi {
|
||||
return Err(SpanLinesError::IllFormedSpan(sp));
|
||||
}
|
||||
|
||||
let lo = self.lookup_char_pos(sp.lo);
|
||||
let hi = self.lookup_char_pos(sp.hi);
|
||||
|
||||
if lo.file.start_pos != hi.file.start_pos {
|
||||
return Err(SpanLinesError::DistinctSources(DistinctSources {
|
||||
begin: (lo.file.name.clone(), lo.file.start_pos),
|
||||
end: (hi.file.name.clone(), hi.file.start_pos),
|
||||
}));
|
||||
}
|
||||
assert!(hi.line >= lo.line);
|
||||
|
||||
let mut lines = Vec::with_capacity(hi.line - lo.line + 1);
|
||||
|
||||
// The span starts partway through the first line,
|
||||
@@ -689,7 +702,7 @@ impl CodeMap {
|
||||
start_col: start_col,
|
||||
end_col: hi.col });
|
||||
|
||||
FileLines {file: lo.file, lines: lines}
|
||||
Ok(FileLines {file: lo.file, lines: lines})
|
||||
}
|
||||
|
||||
pub fn span_to_snippet(&self, sp: Span) -> Result<String, SpanSnippetError> {
|
||||
@@ -914,9 +927,17 @@ impl CodeMap {
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
// SpanSnippetError, DistinctSources, MalformedCodemapPositions
|
||||
// SpanLinesError, SpanSnippetError, DistinctSources, MalformedCodemapPositions
|
||||
//
|
||||
|
||||
pub type FileLinesResult = Result<FileLines, SpanLinesError>;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub enum SpanLinesError {
|
||||
IllFormedSpan(Span),
|
||||
DistinctSources(DistinctSources),
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub enum SpanSnippetError {
|
||||
IllFormedSpan(Span),
|
||||
@@ -1082,7 +1103,7 @@ mod tests {
|
||||
// Test span_to_lines for a span ending at the end of filemap
|
||||
let cm = init_code_map();
|
||||
let span = Span {lo: BytePos(12), hi: BytePos(23), expn_id: NO_EXPANSION};
|
||||
let file_lines = cm.span_to_lines(span);
|
||||
let file_lines = cm.span_to_lines(span).unwrap();
|
||||
|
||||
assert_eq!(file_lines.file.name, "blork.rs");
|
||||
assert_eq!(file_lines.lines.len(), 1);
|
||||
@@ -1127,7 +1148,7 @@ mod tests {
|
||||
assert_eq!(&cm.span_to_snippet(span).unwrap(), "BB\nCCC\nDDDDD");
|
||||
|
||||
// check that span_to_lines gives us the complete result with the lines/cols we expected
|
||||
let lines = cm.span_to_lines(span);
|
||||
let lines = cm.span_to_lines(span).unwrap();
|
||||
let expected = vec![
|
||||
LineInfo { line_index: 1, start_col: CharPos(4), end_col: CharPos(6) },
|
||||
LineInfo { line_index: 2, start_col: CharPos(0), end_col: CharPos(3) },
|
||||
|
||||
Reference in New Issue
Block a user