From 56411443f2421e6726413c212a697a45d45ddfa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 24 Apr 2017 16:27:07 -0700 Subject: [PATCH 1/2] Use diagnostics for trace_macro instead of println --- src/librustc_errors/lib.rs | 6 ++++++ src/libsyntax/ext/base.rs | 3 +++ src/libsyntax/ext/tt/macro_rules.rs | 4 +++- src/test/run-make/trace-macros-flag/Makefile | 9 --------- src/test/run-make/trace-macros-flag/hello.trace | 2 -- .../hello.rs => ui/macros/trace-macro.rs} | 0 src/test/ui/macros/trace-macro.stderr | 14 ++++++++++++++ 7 files changed, 26 insertions(+), 12 deletions(-) delete mode 100644 src/test/run-make/trace-macros-flag/Makefile delete mode 100644 src/test/run-make/trace-macros-flag/hello.trace rename src/test/{run-make/trace-macros-flag/hello.rs => ui/macros/trace-macro.rs} (100%) create mode 100644 src/test/ui/macros/trace-macro.stderr diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 02d8297dd4614..06aafa0505294 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -388,6 +388,12 @@ impl Handler { pub fn span_note_without_error>(&self, sp: S, msg: &str) { self.emit(&sp.into(), msg, Note); } + pub fn span_label_without_error(&self, sp: Span, msg: &str, lbl: &str) { + let mut db = DiagnosticBuilder::new(self, Note, msg); + db.set_span(sp); + db.span_label(sp, &lbl); + db.emit(); + } pub fn span_unimpl>(&self, sp: S, msg: &str) -> ! { self.span_bug(sp, &format!("unimplemented {}", msg)); } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index fda026fec64ef..3bfa63a022d08 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -765,6 +765,9 @@ impl<'a> ExtCtxt<'a> { pub fn span_bug(&self, sp: Span, msg: &str) -> ! { self.parse_sess.span_diagnostic.span_bug(sp, msg); } + pub fn span_label_without_error(&self, sp: Span, msg: &str, label: &str) { + self.parse_sess.span_diagnostic.span_label_without_error(sp, msg, label); + } pub fn bug(&self, msg: &str) -> ! { self.parse_sess.span_diagnostic.bug(msg); } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index be979960725a9..46c49ffb24c45 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -93,7 +93,9 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt, rhses: &[quoted::TokenTree]) -> Box { if cx.trace_macros() { - println!("{}! {{ {} }}", name, arg); + cx.span_label_without_error(sp, + &"trace_macro", + &format!("expands to `{}! {{ {} }}`", name, arg)); } // Which arm's failure should we report? (the one furthest along) diff --git a/src/test/run-make/trace-macros-flag/Makefile b/src/test/run-make/trace-macros-flag/Makefile deleted file mode 100644 index 3338e394e0ef9..0000000000000 --- a/src/test/run-make/trace-macros-flag/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# This test verifies that "-Z trace-macros" works as it should. The traditional -# "hello world" program provides a small example of this as not only println! is -# listed, but also print! (since println! expands to this) - --include ../tools.mk - -all: - $(RUSTC) -Z trace-macros hello.rs > $(TMPDIR)/hello.out - diff -u $(TMPDIR)/hello.out hello.trace diff --git a/src/test/run-make/trace-macros-flag/hello.trace b/src/test/run-make/trace-macros-flag/hello.trace deleted file mode 100644 index cf733339eadf6..0000000000000 --- a/src/test/run-make/trace-macros-flag/hello.trace +++ /dev/null @@ -1,2 +0,0 @@ -println! { "Hello, World!" } -print! { concat ! ( "Hello, World!" , "\n" ) } diff --git a/src/test/run-make/trace-macros-flag/hello.rs b/src/test/ui/macros/trace-macro.rs similarity index 100% rename from src/test/run-make/trace-macros-flag/hello.rs rename to src/test/ui/macros/trace-macro.rs diff --git a/src/test/ui/macros/trace-macro.stderr b/src/test/ui/macros/trace-macro.stderr new file mode 100644 index 0000000000000..8f091ef945547 --- /dev/null +++ b/src/test/ui/macros/trace-macro.stderr @@ -0,0 +1,14 @@ +note: trace_macro + --> $DIR/trace-macro.rs:12:5 + | +12 | println!("Hello, World!"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expands to `println! { "Hello, World!" }` + +note: trace_macro + --> $DIR/trace-macro.rs:12:5 + | +12 | println!("Hello, World!"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expands to `print! { concat ! ( "Hello, World!" , "\n" ) }` + | + = note: this error originates in a macro outside of the current crate + From 8c9ad8d72c5a3ad73af33e3ad9a409327645ac28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 5 May 2017 21:49:59 -0700 Subject: [PATCH 2/2] Group "macro expansion" notes per call span --- src/librustc_errors/lib.rs | 8 +++++--- src/libsyntax/ext/base.rs | 13 +++++++++++-- src/libsyntax/ext/expand.rs | 2 +- src/libsyntax/ext/tt/macro_rules.rs | 12 ++++++------ src/test/ui/macros/trace-macro.rs | 2 ++ src/test/ui/macros/trace-macro.stderr | 15 +++++---------- 6 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 06aafa0505294..db8c9ac306bba 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -388,11 +388,13 @@ impl Handler { pub fn span_note_without_error>(&self, sp: S, msg: &str) { self.emit(&sp.into(), msg, Note); } - pub fn span_label_without_error(&self, sp: Span, msg: &str, lbl: &str) { + pub fn span_note_diag<'a>(&'a self, + sp: Span, + msg: &str) + -> DiagnosticBuilder<'a> { let mut db = DiagnosticBuilder::new(self, Note, msg); db.set_span(sp); - db.span_label(sp, &lbl); - db.emit(); + db } pub fn span_unimpl>(&self, sp: S, msg: &str) -> ! { self.span_bug(sp, &format!("unimplemented {}", msg)); diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 3bfa63a022d08..f731c5abdd6a1 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -24,6 +24,7 @@ use ptr::P; use symbol::Symbol; use util::small_vector::SmallVector; +use std::collections::HashMap; use std::path::PathBuf; use std::rc::Rc; use std::default::Default; @@ -643,6 +644,7 @@ pub struct ExtCtxt<'a> { pub resolver: &'a mut Resolver, pub resolve_err_count: usize, pub current_expansion: ExpansionData, + pub expansions: HashMap>, } impl<'a> ExtCtxt<'a> { @@ -662,6 +664,7 @@ impl<'a> ExtCtxt<'a> { module: Rc::new(ModuleData { mod_path: Vec::new(), directory: PathBuf::new() }), directory_ownership: DirectoryOwnership::Owned, }, + expansions: HashMap::new(), } } @@ -765,8 +768,14 @@ impl<'a> ExtCtxt<'a> { pub fn span_bug(&self, sp: Span, msg: &str) -> ! { self.parse_sess.span_diagnostic.span_bug(sp, msg); } - pub fn span_label_without_error(&self, sp: Span, msg: &str, label: &str) { - self.parse_sess.span_diagnostic.span_label_without_error(sp, msg, label); + pub fn trace_macros_diag(&self) { + for (sp, notes) in self.expansions.iter() { + let mut db = self.parse_sess.span_diagnostic.span_note_diag(*sp, &"trace_macro"); + for note in notes { + db.note(¬e); + } + db.emit(); + } } pub fn bug(&self, msg: &str) -> ! { self.parse_sess.span_diagnostic.bug(msg); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 2db295d013639..31d4cc779c25e 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -231,7 +231,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }, _ => unreachable!(), }; - + self.cx.trace_macros_diag(); krate } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 46c49ffb24c45..f959ccc989e2e 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -27,8 +27,8 @@ use symbol::Symbol; use tokenstream::{TokenStream, TokenTree}; use std::cell::RefCell; -use std::collections::{HashMap}; -use std::collections::hash_map::{Entry}; +use std::collections::HashMap; +use std::collections::hash_map::Entry; use std::rc::Rc; pub struct ParserAnyMacro<'a> { @@ -85,7 +85,7 @@ impl TTMacroExpander for MacroRulesMacroExpander { } /// Given `lhses` and `rhses`, this is the new macro we create -fn generic_extension<'cx>(cx: &'cx ExtCtxt, +fn generic_extension<'cx>(cx: &'cx mut ExtCtxt, sp: Span, name: ast::Ident, arg: TokenStream, @@ -93,9 +93,9 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt, rhses: &[quoted::TokenTree]) -> Box { if cx.trace_macros() { - cx.span_label_without_error(sp, - &"trace_macro", - &format!("expands to `{}! {{ {} }}`", name, arg)); + let sp = sp.macro_backtrace().last().map(|trace| trace.call_site).unwrap_or(sp); + let mut values: &mut Vec = cx.expansions.entry(sp).or_insert(vec![]); + values.push(format!("expands to `{}! {{ {} }}`", name, arg)); } // Which arm's failure should we report? (the one furthest along) diff --git a/src/test/ui/macros/trace-macro.rs b/src/test/ui/macros/trace-macro.rs index 42d3d4c799df8..34f674ae016a5 100644 --- a/src/test/ui/macros/trace-macro.rs +++ b/src/test/ui/macros/trace-macro.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// compile-flags: -Z trace-macros + fn main() { println!("Hello, World!"); } diff --git a/src/test/ui/macros/trace-macro.stderr b/src/test/ui/macros/trace-macro.stderr index 8f091ef945547..09117a4ca7404 100644 --- a/src/test/ui/macros/trace-macro.stderr +++ b/src/test/ui/macros/trace-macro.stderr @@ -1,14 +1,9 @@ note: trace_macro - --> $DIR/trace-macro.rs:12:5 + --> $DIR/trace-macro.rs:14:5 | -12 | println!("Hello, World!"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expands to `println! { "Hello, World!" }` - -note: trace_macro - --> $DIR/trace-macro.rs:12:5 - | -12 | println!("Hello, World!"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expands to `print! { concat ! ( "Hello, World!" , "\n" ) }` +14 | println!("Hello, World!"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate + = note: expands to `println! { "Hello, World!" }` + = note: expands to `print! { concat ! ( "Hello, World!" , "/n" ) }`