Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not ICE on malformed suggestion spans #68256

Merged
merged 2 commits into from
Jan 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions src/librustc_errors/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1476,6 +1476,15 @@ impl EmitterWriter {
None => return Ok(()),
};

// Render the replacements for each suggestion
let suggestions = suggestion.splice_lines(&**sm);

if suggestions.is_empty() {
// Suggestions coming from macros can have malformed spans. This is a heavy handed
// approach to avoid ICEs by ignoring the suggestion outright.
return Ok(());
}

let mut buffer = StyledBuffer::new();

// Render the suggestion message
Expand All @@ -1492,9 +1501,6 @@ impl EmitterWriter {
Some(Style::HeaderMsg),
);

// Render the replacements for each suggestion
let suggestions = suggestion.splice_lines(&**sm);

let mut row_num = 2;
let mut notice_capitalization = false;
for (complete, parts, only_capitalization) in suggestions.iter().take(MAX_SUGGESTIONS) {
Expand All @@ -1505,7 +1511,9 @@ impl EmitterWriter {
let show_underline = !(parts.len() == 1 && parts[0].snippet.trim() == complete.trim())
&& complete.lines().count() == 1;

let lines = sm.span_to_lines(parts[0].span).unwrap();
let lines = sm
.span_to_lines(parts[0].span)
estebank marked this conversation as resolved.
Show resolved Hide resolved
.expect("span_to_lines failed when emitting suggestion");

assert!(!lines.lines.is_empty());

Expand Down
10 changes: 10 additions & 0 deletions src/librustc_errors/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

pub use emitter::ColorConfig;

use log::debug;
use Level::*;

use emitter::{is_case_difference, Emitter, EmitterWriter};
Expand Down Expand Up @@ -174,6 +175,15 @@ impl CodeSuggestion {

self.substitutions
.iter()
.filter(|subst| {
// Suggestions coming from macros can have malformed spans. This is a heavy
// handed approach to avoid ICEs by ignoring the suggestion outright.
let invalid = subst.parts.iter().any(|item| cm.is_valid_span(item.span).is_err());
if invalid {
debug!("splice_lines: suggestion contains an invalid span: {:?}", subst);
}
!invalid
})
.cloned()
.map(|mut substitution| {
// Assumption: all spans are in the same file, and all spans
Expand Down
11 changes: 7 additions & 4 deletions src/librustc_span/source_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -473,20 +473,23 @@ impl SourceMap {
lo.line != hi.line
}

pub fn span_to_lines(&self, sp: Span) -> FileLinesResult {
debug!("span_to_lines(sp={:?})", sp);

pub fn is_valid_span(&self, sp: Span) -> Result<(Loc, Loc), SpanLinesError> {
let lo = self.lookup_char_pos(sp.lo());
debug!("span_to_lines: lo={:?}", lo);
let hi = self.lookup_char_pos(sp.hi());
debug!("span_to_lines: hi={:?}", 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),
}));
}
Ok((lo, hi))
}

pub fn span_to_lines(&self, sp: Span) -> FileLinesResult {
debug!("span_to_lines(sp={:?})", sp);
let (lo, hi) = self.is_valid_span(sp)?;
assert!(hi.line >= lo.line);

let mut lines = Vec::with_capacity(hi.line - lo.line + 1);
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/miri_unleashed/mutable_const2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ error: internal compiler error: mutable allocation in constant
LL | const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:346:17
thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:356:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

error: internal compiler error: unexpected panic
Expand Down