Rollup merge of #68256 - estebank:bad-sugg-span, r=petrochenkov

Do not ICE on malformed suggestion spans

Under the assumption that suggestions are by their very nature always "best effort", it is ok if we don't display them instead of having an ICE. The underlying issue of the malformed span being _created_ is left unaddressed.

Fix #67567.

r? @petrochenkov
This commit is contained in:
Tyler Mandry 2020-01-17 17:28:15 -08:00 committed by GitHub
commit 7f6fdef0e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 9 deletions

View File

@ -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
@ -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) {
@ -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)
.expect("span_to_lines failed when emitting suggestion");
assert!(!lines.lines.is_empty());

View File

@ -10,6 +10,7 @@
pub use emitter::ColorConfig;
use log::debug;
use Level::*;
use emitter::{is_case_difference, Emitter, EmitterWriter};
@ -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

View File

@ -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);

View File

@ -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