]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_errors/emitter.rs
Auto merge of #68633 - JohnTitor:avoid-ice-in-diagnostics, r=estebank
[rust.git] / src / librustc_errors / emitter.rs
index 7218730538a4b40c54ee013aa74d9ac4ab2bf160..1fcb36a2a30908408b9b43c5d05fcc0fd9fa661b 100644 (file)
     pluralize, CodeSuggestion, Diagnostic, DiagnosticId, Level, SubDiagnostic, SuggestionStyle,
 };
 
+use log::*;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
+use rustc_span::hygiene::{ExpnKind, MacroKind};
 use std::borrow::Cow;
 use std::cmp::{max, min, Reverse};
 use std::io;
@@ -342,19 +344,20 @@ fn fix_multispan_in_std_macros(
             if call_sp != *sp && !always_backtrace {
                 before_after.push((*sp, call_sp));
             }
-            let backtrace_len = sp.macro_backtrace().len();
-            for (i, trace) in sp.macro_backtrace().iter().rev().enumerate() {
+            let macro_backtrace: Vec<_> = sp.macro_backtrace().collect();
+            let backtrace_len = macro_backtrace.len();
+            for (i, trace) in macro_backtrace.iter().rev().enumerate() {
                 // Only show macro locations that are local
                 // and display them like a span_note
-                if trace.def_site_span.is_dummy() {
+                if trace.def_site.is_dummy() {
                     continue;
                 }
                 if always_backtrace {
                     new_labels.push((
-                        trace.def_site_span,
+                        trace.def_site,
                         format!(
                             "in this expansion of `{}`{}",
-                            trace.macro_decl_name,
+                            trace.kind.descr(),
                             if backtrace_len > 2 {
                                 // if backtrace_len == 1 it'll be pointed
                                 // at by "in this macro invocation"
@@ -366,9 +369,8 @@ fn fix_multispan_in_std_macros(
                     ));
                 }
                 // Check to make sure we're not in any <*macros>
-                if !sm.span_to_filename(trace.def_site_span).is_macros()
-                    && !trace.macro_decl_name.starts_with("desugaring of ")
-                    && !trace.macro_decl_name.starts_with("#[")
+                if !sm.span_to_filename(trace.def_site).is_macros()
+                    && matches!(trace.kind, ExpnKind::Macro(MacroKind::Bang, _))
                     || always_backtrace
                 {
                     new_labels.push((
@@ -398,9 +400,8 @@ fn fix_multispan_in_std_macros(
                 continue;
             }
             if sm.span_to_filename(sp_label.span.clone()).is_macros() && !always_backtrace {
-                let v = sp_label.span.macro_backtrace();
-                if let Some(use_site) = v.last() {
-                    before_after.push((sp_label.span.clone(), use_site.call_site.clone()));
+                if let Some(use_site) = sp_label.span.macro_backtrace().last() {
+                    before_after.push((sp_label.span, use_site.call_site));
                 }
             }
         }
@@ -1184,13 +1185,13 @@ fn emit_message_default(
             let level_str = level.to_string();
             // The failure note level itself does not provide any useful diagnostic information
             if *level != Level::FailureNote && !level_str.is_empty() {
-                buffer.append(0, &level_str, Style::Level(level.clone()));
+                buffer.append(0, &level_str, Style::Level(*level));
             }
             // only render error codes, not lint codes
             if let Some(DiagnosticId::Error(ref code)) = *code {
-                buffer.append(0, "[", Style::Level(level.clone()));
-                buffer.append(0, &code, Style::Level(level.clone()));
-                buffer.append(0, "]", Style::Level(level.clone()));
+                buffer.append(0, "[", Style::Level(*level));
+                buffer.append(0, &code, Style::Level(*level));
+                buffer.append(0, "]", Style::Level(*level));
             }
             if *level != Level::FailureNote && !level_str.is_empty() {
                 buffer.append(0, ": ", header_style);
@@ -1366,7 +1367,7 @@ fn emit_message_default(
                 } else if self.ui_testing {
                     140
                 } else {
-                    term_size::dimensions()
+                    termize::dimensions()
                         .map(|(w, _)| w.saturating_sub(code_offset))
                         .unwrap_or(std::usize::MAX)
                 };
@@ -1495,7 +1496,7 @@ fn emit_suggestion_default(
         // Render the suggestion message
         let level_str = level.to_string();
         if !level_str.is_empty() {
-            buffer.append(0, &level_str, Style::Level(level.clone()));
+            buffer.append(0, &level_str, Style::Level(*level));
             buffer.append(0, ": ", Style::HeaderMsg);
         }
         self.msg_to_buffer(
@@ -2108,7 +2109,13 @@ fn drop(&mut self) {
 /// Whether the original and suggested code are visually similar enough to warrant extra wording.
 pub fn is_case_difference(sm: &SourceMap, suggested: &str, sp: Span) -> bool {
     // FIXME: this should probably be extended to also account for `FO0` → `FOO` and unicode.
-    let found = sm.span_to_snippet(sp).unwrap();
+    let found = match sm.span_to_snippet(sp) {
+        Ok(snippet) => snippet,
+        Err(e) => {
+            warn!("Invalid span {:?}. Err={:?}", sp, e);
+            return false;
+        }
+    };
     let ascii_confusables = &['c', 'f', 'i', 'k', 'o', 's', 'u', 'v', 'w', 'x', 'y', 'z'];
     // All the chars that differ in capitalization are confusable (above):
     let confusable = found