about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-12-14 07:06:02 +0000
committerbors <bors@rust-lang.org>2017-12-14 07:06:02 +0000
commit8954b16beb844fcac0cefe229e1c714a17de16e5 (patch)
tree07e11d44c2885af6b96cf276f5c62d9d3ad4acaf /src
parentf03e06762ea6c4116c360185c0e9b6f209b76959 (diff)
parentd4b8e99540ed815f7c0187cf2db8a2e4c0a61d8f (diff)
downloadrust-8954b16beb844fcac0cefe229e1c714a17de16e5.tar.gz
rust-8954b16beb844fcac0cefe229e1c714a17de16e5.zip
Auto merge of #46605 - estebank:macro-backtrace-spans, r=pnkfelix
Use spans for -Z external-macro-backtrace

```
% rustc ui/type-check/cannot_infer_local_or_vec.rs -Z external-macro-backtrace
error[E0282]: type annotations needed
  --> <vec macros>:3:1
   |
1  | / ( $ elem : expr ; $ n : expr ) => (
2  | | $ crate :: vec :: from_elem ( $ elem , $ n ) ) ; ( $ ( $ x : expr ) , * ) => (
3  | | < [ _ ] > :: into_vec ( box [ $ ( $ x ) , * ] ) ) ; ( $ ( $ x : expr , ) * )
   | | ^^^^^^^^^^^^^^^^^^^^^
   | | |
   | | cannot infer type for `T`
4  | | => ( vec ! [ $ ( $ x ) , * ] )
   | |______________________________- in this expansion of `vec!`
   |
  ::: ui/type-check/cannot_infer_local_or_vec.rs
   |
12 |       let x = vec![];
   |           -   ------ in this macro invocation
   |           |
   |           consider giving `x` a type

error: aborting due to previous error
```
Diffstat (limited to 'src')
-rw-r--r--src/librustc_errors/emitter.rs102
-rw-r--r--src/test/ui/macro_backtrace/auxiliary/ping.rs21
-rw-r--r--src/test/ui/macro_backtrace/main.rs7
-rw-r--r--src/test/ui/macro_backtrace/main.stderr77
4 files changed, 144 insertions, 63 deletions
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 439ded40ec1..a9c934e9713 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -64,11 +64,11 @@ impl Emitter for EmitterWriter {
             }
         }
 
-        if !db.handler.flags.external_macro_backtrace {
-            self.fix_multispans_in_std_macros(&mut primary_span, &mut children);
-        }
+        self.fix_multispans_in_std_macros(&mut primary_span,
+                                          &mut children,
+                                          db.handler.flags.external_macro_backtrace);
+
         self.emit_messages_default(&db.level,
-                                   db.handler.flags.external_macro_backtrace,
                                    &db.styled_message(),
                                    &db.code,
                                    &primary_span,
@@ -726,7 +726,9 @@ impl EmitterWriter {
     // This "fixes" MultiSpans that contain Spans that are pointing to locations inside of
     // <*macros>. Since these locations are often difficult to read, we move these Spans from
     // <*macros> to their corresponding use site.
-    fn fix_multispan_in_std_macros(&mut self, span: &mut MultiSpan) -> bool {
+    fn fix_multispan_in_std_macros(&mut self,
+                                   span: &mut MultiSpan,
+                                   always_backtrace: bool) -> bool {
         let mut spans_updated = false;
 
         if let Some(ref cm) = self.cm {
@@ -739,22 +741,45 @@ impl EmitterWriter {
                     continue;
                 }
                 let call_sp = cm.call_span_if_macro(*sp);
-                if call_sp != *sp {
-                    before_after.push((sp.clone(), call_sp));
+                if call_sp != *sp && !always_backtrace {
+                    before_after.push((*sp, call_sp));
                 }
-                for trace in sp.macro_backtrace().iter().rev() {
+                let backtrace_len = sp.macro_backtrace().len();
+                for (i, trace) in sp.macro_backtrace().iter().rev().enumerate() {
                     // Only show macro locations that are local
                     // and display them like a span_note
                     if let Some(def_site) = trace.def_site_span {
                         if def_site == DUMMY_SP {
                             continue;
                         }
+                        if always_backtrace {
+                            new_labels.push((def_site,
+                                             format!("in this expansion of `{}`{}",
+                                                     trace.macro_decl_name,
+                                                     if backtrace_len > 2 {
+                                                         // if backtrace_len == 1 it'll be pointed
+                                                         // at by "in this macro invocation"
+                                                         format!(" (#{})", i + 1)
+                                                     } else {
+                                                         "".to_string()
+                                                     })));
+                        }
                         // Check to make sure we're not in any <*macros>
                         if !cm.span_to_filename(def_site).contains("macros>") &&
-                           !trace.macro_decl_name.starts_with("#[") {
+                           !trace.macro_decl_name.starts_with("#[") ||
+                           always_backtrace {
                             new_labels.push((trace.call_site,
-                                             "in this macro invocation".to_string()));
-                            break;
+                                             format!("in this macro invocation{}",
+                                                     if backtrace_len > 2 && always_backtrace {
+                                                         // only specify order when the macro
+                                                         // backtrace is multiple levels deep
+                                                         format!(" (#{})", i + 1)
+                                                     } else {
+                                                         "".to_string()
+                                                     })));
+                            if !always_backtrace {
+                                break;
+                            }
                         }
                     }
                 }
@@ -766,7 +791,9 @@ impl EmitterWriter {
                 if sp_label.span == DUMMY_SP {
                     continue;
                 }
-                if cm.span_to_filename(sp_label.span.clone()).contains("macros>") {
+                if cm.span_to_filename(sp_label.span.clone()).contains("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()));
@@ -788,18 +815,19 @@ impl EmitterWriter {
     // will change the span to point at the use site.
     fn fix_multispans_in_std_macros(&mut self,
                                     span: &mut MultiSpan,
-                                    children: &mut Vec<SubDiagnostic>) {
-        let mut spans_updated = self.fix_multispan_in_std_macros(span);
+                                    children: &mut Vec<SubDiagnostic>,
+                                    backtrace: bool) {
+        let mut spans_updated = self.fix_multispan_in_std_macros(span, backtrace);
         for child in children.iter_mut() {
-            spans_updated |= self.fix_multispan_in_std_macros(&mut child.span);
+            spans_updated |= self.fix_multispan_in_std_macros(&mut child.span, backtrace);
         }
         if spans_updated {
             children.push(SubDiagnostic {
                 level: Level::Note,
                 message: vec![
-                    (["this error originates in a macro outside of the current crate",
-                      "(in Nightly builds, run with -Z external-macro-backtrace for more info)"]
-                      .join(" "),
+                    ("this error originates in a macro outside of the current crate \
+                      (in Nightly builds, run with -Z external-macro-backtrace \
+                       for more info)".to_string(),
                      Style::NoStyle),
                 ],
                 span: MultiSpan::new(),
@@ -861,7 +889,7 @@ impl EmitterWriter {
         //       ("see?", Style::Highlight),
         //     ];
         //
-        // the expected output on a note is (* surround the  highlighted text)
+        // the expected output on a note is (* surround the highlighted text)
         //
         //        = note: highlighted multiline
         //                string to
@@ -889,7 +917,6 @@ impl EmitterWriter {
                             msg: &Vec<(String, Style)>,
                             code: &Option<DiagnosticId>,
                             level: &Level,
-                            external_macro_backtrace: bool,
                             max_line_num_len: usize,
                             is_secondary: bool)
                             -> io::Result<()> {
@@ -1087,18 +1114,13 @@ impl EmitterWriter {
             }
         }
 
-        if external_macro_backtrace {
-            if let Some(ref primary_span) = msp.primary_span().as_ref() {
-                self.render_macro_backtrace_old_school(primary_span, &mut buffer)?;
-            }
-        }
-
         // final step: take our styled buffer, render it, then output it
         emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?;
 
         Ok(())
 
     }
+
     fn emit_suggestion_default(&mut self,
                                suggestion: &CodeSuggestion,
                                level: &Level,
@@ -1182,9 +1204,9 @@ impl EmitterWriter {
         }
         Ok(())
     }
+
     fn emit_messages_default(&mut self,
                              level: &Level,
-                             external_macro_backtrace: bool,
                              message: &Vec<(String, Style)>,
                              code: &Option<DiagnosticId>,
                              span: &MultiSpan,
@@ -1197,7 +1219,6 @@ impl EmitterWriter {
                                         message,
                                         code,
                                         level,
-                                        external_macro_backtrace,
                                         max_line_num_len,
                                         false) {
             Ok(()) => {
@@ -1219,7 +1240,6 @@ impl EmitterWriter {
                                                         &child.styled_message(),
                                                         &None,
                                                         &child.level,
-                                                        external_macro_backtrace,
                                                         max_line_num_len,
                                                         true) {
                             Err(e) => panic!("failed to emit error: {}", e),
@@ -1248,30 +1268,6 @@ impl EmitterWriter {
             }
         }
     }
-
-    fn render_macro_backtrace_old_school(&self,
-                                         sp: &Span,
-                                         buffer: &mut StyledBuffer) -> io::Result<()> {
-        if let Some(ref cm) = self.cm {
-            for trace in sp.macro_backtrace().iter().rev() {
-                let line_offset = buffer.num_lines();
-
-                let mut diag_string =
-                    format!("in this expansion of {}", trace.macro_decl_name);
-                if let Some(def_site_span) = trace.def_site_span {
-                    diag_string.push_str(
-                        &format!(" (defined in {})",
-                            cm.span_to_filename(def_site_span)));
-                }
-                let snippet = cm.span_to_string(trace.call_site);
-                buffer.append(line_offset, &format!("{} ", snippet), Style::NoStyle);
-                buffer.append(line_offset, "note", Style::Level(Level::Note));
-                buffer.append(line_offset, ": ", Style::NoStyle);
-                buffer.append(line_offset, &diag_string, Style::OldSchoolNoteText);
-            }
-        }
-        Ok(())
-    }
 }
 
 fn draw_col_separator(buffer: &mut StyledBuffer, line: usize, col: usize) {
diff --git a/src/test/ui/macro_backtrace/auxiliary/ping.rs b/src/test/ui/macro_backtrace/auxiliary/ping.rs
index eeed0d78158..e4131dde8f7 100644
--- a/src/test/ui/macro_backtrace/auxiliary/ping.rs
+++ b/src/test/ui/macro_backtrace/auxiliary/ping.rs
@@ -18,3 +18,24 @@ macro_rules! ping {
     }
 }
 
+#[macro_export]
+macro_rules! deep {
+    () => {
+        foo!();
+    }
+}
+
+#[macro_export]
+macro_rules! foo {
+    () => {
+        bar!();
+    }
+}
+
+#[macro_export]
+macro_rules! bar {
+    () => {
+        ping!();
+    }
+}
+
diff --git a/src/test/ui/macro_backtrace/main.rs b/src/test/ui/macro_backtrace/main.rs
index ec9218e3ec0..72a5c0d5e37 100644
--- a/src/test/ui/macro_backtrace/main.rs
+++ b/src/test/ui/macro_backtrace/main.rs
@@ -16,11 +16,14 @@
 
 // a local macro
 macro_rules! pong {
-    () => { syntax error }; //~ ERROR expected one of
-    //~^ ERROR expected one of
+    () => { syntax error };
 }
+//~^^ ERROR expected one of
+//~| ERROR expected one of
+//~| ERROR expected one of
 
 fn main() {
     pong!();
     ping!();
+    deep!();
 }
diff --git a/src/test/ui/macro_backtrace/main.stderr b/src/test/ui/macro_backtrace/main.stderr
index 4b10e5e19a3..5990f71b3ca 100644
--- a/src/test/ui/macro_backtrace/main.stderr
+++ b/src/test/ui/macro_backtrace/main.stderr
@@ -1,17 +1,78 @@
 error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error`
   --> $DIR/main.rs:19:20
    |
-19 |     () => { syntax error }; //~ ERROR expected one of
-   |                    ^^^^^ expected one of 8 possible tokens here
-$DIR/main.rs:24:5: 24:13 note: in this expansion of pong! (defined in $DIR/main.rs)
+18 | / macro_rules! pong {
+19 | |     () => { syntax error };
+   | |                    ^^^^^ expected one of 8 possible tokens here
+20 | | }
+   | |_- in this expansion of `pong!`
+...
+26 |       pong!();
+   |       -------- in this macro invocation
 
 error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error`
   --> $DIR/main.rs:19:20
    |
-19 |     () => { syntax error }; //~ ERROR expected one of
-   |                    ^^^^^ expected one of 8 possible tokens here
-$DIR/main.rs:25:5: 25:13 note: in this expansion of ping! (defined in <ping macros>)
-<ping macros>:1:11: 1:24 note: in this expansion of pong! (defined in $DIR/main.rs)
+18 | / macro_rules! pong {
+19 | |     () => { syntax error };
+   | |                    ^^^^^ expected one of 8 possible tokens here
+20 | | }
+   | |_- in this expansion of `pong!`
+...
+27 |       ping!();
+   |       -------- in this macro invocation
+   | 
+  ::: <ping macros>
+   |
+1  |   (  ) => { pong ! (  ) ; }
+   |   -------------------------
+   |   |         |
+   |   |         in this macro invocation
+   |   in this expansion of `ping!`
+
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error`
+  --> $DIR/main.rs:19:20
+   |
+18 | / macro_rules! pong {
+19 | |     () => { syntax error };
+   | |                    ^^^^^ expected one of 8 possible tokens here
+20 | | }
+   | |_- in this expansion of `pong!` (#5)
+...
+28 |       deep!();
+   |       -------- in this macro invocation (#1)
+   | 
+  ::: <deep macros>
+   |
+1  |   (  ) => { foo ! (  ) ; }
+   |   ------------------------
+   |   |         |
+   |   |         in this macro invocation (#2)
+   |   in this expansion of `deep!` (#1)
+   | 
+  ::: <foo macros>
+   |
+1  |   (  ) => { bar ! (  ) ; }
+   |   ------------------------
+   |   |         |
+   |   |         in this macro invocation (#3)
+   |   in this expansion of `foo!` (#2)
+   | 
+  ::: <bar macros>
+   |
+1  |   (  ) => { ping ! (  ) ; }
+   |   -------------------------
+   |   |         |
+   |   |         in this macro invocation (#4)
+   |   in this expansion of `bar!` (#3)
+   | 
+  ::: <ping macros>
+   |
+1  |   (  ) => { pong ! (  ) ; }
+   |   -------------------------
+   |   |         |
+   |   |         in this macro invocation (#5)
+   |   in this expansion of `ping!` (#4)
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors