diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2020-01-15 09:57:06 -0800 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2020-01-16 18:14:26 -0800 |
| commit | 10a9ea4c2622544d52ecef47fea0404a7ce0ace4 (patch) | |
| tree | efa08d91a8cd3f999d0f39741222eb497b20ca04 /src | |
| parent | ecbc222855c890c3aabe4848e8d8b312debcf0ff (diff) | |
Do not ICE on malformed suggestion spans
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_errors/emitter.rs | 9 | ||||
| -rw-r--r-- | src/librustc_errors/lib.rs | 13 | ||||
| -rw-r--r-- | src/librustc_span/source_map.rs | 11 | ||||
| -rw-r--r-- | src/test/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 526b4e2971b..e37496f7299 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 e24e8719133..889c84d6da1 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<SubstitutionPart>, bool)> { diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs index fb5fcf4a830..9c7c0f0c8b0 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 655c31763ef..cc124058cfc 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 |
