From 10a9ea4c2622544d52ecef47fea0404a7ce0ace4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 15 Jan 2020 09:57:06 -0800 Subject: [PATCH] Do not ICE on malformed suggestion spans --- src/librustc_errors/emitter.rs | 9 ++++++++- src/librustc_errors/lib.rs | 13 +++++++++++++ src/librustc_span/source_map.rs | 11 +++++++---- .../ui/consts/miri_unleashed/mutable_const2.stderr | 2 +- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 526b4e2971be..e37496f72995 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -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()); diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index e24e8719133a..889c84d6da13 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -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, bool)> { diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs index fb5fcf4a8303..9c7c0f0c8b0e 100644 --- a/src/librustc_span/source_map.rs +++ b/src/librustc_span/source_map.rs @@ -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); diff --git a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr index 655c31763ef4..cc124058cfcb 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr +++ b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr @@ -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