Do not ICE on malformed suggestion spans
This commit is contained in:
parent
ecbc222855
commit
10a9ea4c26
4 changed files with 29 additions and 6 deletions
|
|
@ -1475,6 +1475,11 @@ impl EmitterWriter {
|
|||
Some(ref sm) => sm,
|
||||
None => return Ok(()),
|
||||
};
|
||||
if !suggestion.has_valid_spans(&**sm) {
|
||||
// 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();
|
||||
|
||||
|
|
@ -1505,7 +1510,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());
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
pub use emitter::ColorConfig;
|
||||
|
||||
use log::debug;
|
||||
use Level::*;
|
||||
|
||||
use emitter::{is_case_difference, Emitter, EmitterWriter};
|
||||
|
|
@ -143,6 +144,18 @@ pub struct SubstitutionPart {
|
|||
}
|
||||
|
||||
impl CodeSuggestion {
|
||||
/// Suggestions coming from macros can have malformed spans. This is a heavy handed approach
|
||||
/// to avoid ICEs by ignoring the suggestion outright.
|
||||
pub fn has_valid_spans(&self, cm: &SourceMap) -> bool {
|
||||
!self.substitutions.iter().any(|subst| {
|
||||
let invalid = subst.parts.iter().any(|item| cm.is_valid_span(item.span).is_err());
|
||||
if invalid {
|
||||
debug!("malformed span in suggestion: {:?}", subst);
|
||||
}
|
||||
invalid
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the assembled code suggestions, whether they should be shown with an underline
|
||||
/// and whether the substitution only differs in capitalization.
|
||||
pub fn splice_lines(&self, cm: &SourceMap) -> Vec<(String, Vec<SubstitutionPart>, bool)> {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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:359:17
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
|
||||
error: internal compiler error: unexpected panic
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue