From b541d3da5d9f89407c7072f4a6d65872cf30a577 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 31 May 2020 16:20:50 -0400 Subject: [PATCH] Add `-Z span-debug` to allow for easier debugging of proc macros Currently, the `Debug` impl for `proc_macro::Span` just prints out the byte range. This can make debugging proc macros (either as a crate author or as a compiler developer) very frustrating, since neither the actual filename nor the `SyntaxContext` is displayed. This commit adds a perma-unstable flag `-Z span-debug`. When enabled, the `Debug` impl for `proc_macro::Span` simply forwards directly to `rustc_span::Span`. Once #72618 is merged, this will start displaying actual line numbers. While `Debug` impls are not subject to Rust's normal stability guarnatees, we probably shouldn't expose any additional information on stable until `#![feature(proc_macro_span)]` is stabilized. Otherwise, we would be providing a 'backdoor' way to access information that's supposed be behind unstable APIs. --- src/librustc_expand/expand.rs | 2 + src/librustc_expand/proc_macro_server.rs | 8 +- src/librustc_interface/passes.rs | 1 + src/librustc_interface/tests.rs | 1 + src/librustc_session/options.rs | 2 + .../proc-macro/debug/dump-debug-span-debug.rs | 41 +++++ .../debug/dump-debug-span-debug.stderr | 166 ++++++++++++++++++ 7 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/proc-macro/debug/dump-debug-span-debug.rs create mode 100644 src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index 5214ca0dc7fff..4e41bd4bbfa08 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -1789,6 +1789,7 @@ pub struct ExpansionConfig<'feat> { pub trace_mac: bool, pub should_test: bool, // If false, strip `#[test]` nodes pub keep_macs: bool, + pub span_debug: bool, // If true, use verbose debugging for `proc_macro::Span` } impl<'feat> ExpansionConfig<'feat> { @@ -1800,6 +1801,7 @@ impl<'feat> ExpansionConfig<'feat> { trace_mac: false, should_test: false, keep_macs: false, + span_debug: false, } } diff --git a/src/librustc_expand/proc_macro_server.rs b/src/librustc_expand/proc_macro_server.rs index 36af83711f7e4..79fa091ba1808 100644 --- a/src/librustc_expand/proc_macro_server.rs +++ b/src/librustc_expand/proc_macro_server.rs @@ -352,6 +352,7 @@ pub(crate) struct Rustc<'a> { def_site: Span, call_site: Span, mixed_site: Span, + span_debug: bool, } impl<'a> Rustc<'a> { @@ -362,6 +363,7 @@ impl<'a> Rustc<'a> { def_site: cx.with_def_site_ctxt(expn_data.def_site), call_site: cx.with_call_site_ctxt(expn_data.call_site), mixed_site: cx.with_mixed_site_ctxt(expn_data.call_site), + span_debug: cx.ecfg.span_debug, } } @@ -646,7 +648,11 @@ impl server::Diagnostic for Rustc<'_> { impl server::Span for Rustc<'_> { fn debug(&mut self, span: Self::Span) -> String { - format!("{:?} bytes({}..{})", span.ctxt(), span.lo().0, span.hi().0) + if self.span_debug { + format!("{:?}", span) + } else { + format!("{:?} bytes({}..{})", span.ctxt(), span.lo().0, span.hi().0) + } } fn def_site(&mut self) -> Self::Span { self.def_site diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index a01170db807f2..9a60e74d94d01 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -291,6 +291,7 @@ fn configure_and_expand_inner<'a>( recursion_limit: sess.recursion_limit(), trace_mac: sess.opts.debugging_opts.trace_macros, should_test: sess.opts.test, + span_debug: sess.opts.debugging_opts.span_debug, ..rustc_expand::expand::ExpansionConfig::default(crate_name.to_string()) }; diff --git a/src/librustc_interface/tests.rs b/src/librustc_interface/tests.rs index 18cbea858d47a..87647f3b0b017 100644 --- a/src/librustc_interface/tests.rs +++ b/src/librustc_interface/tests.rs @@ -506,6 +506,7 @@ fn test_debugging_options_tracking_hash() { untracked!(save_analysis, true); untracked!(self_profile, SwitchWithOptPath::Enabled(None)); untracked!(self_profile_events, Some(vec![String::new()])); + untracked!(span_debug, true); untracked!(span_free_formats, true); untracked!(strip, Strip::None); untracked!(terminal_width, Some(80)); diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs index a38e7f063d79a..d22c6ec9d7d01 100644 --- a/src/librustc_session/options.rs +++ b/src/librustc_session/options.rs @@ -996,6 +996,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "make the current crate share its generic instantiations"), show_span: Option = (None, parse_opt_string, [TRACKED], "show spans for compiler debugging (expr|pat|ty)"), + span_debug: bool = (false, parse_bool, [UNTRACKED], + "forward proc_macro::Span's `Debug` impl to `Span`"), // o/w tests have closure@path span_free_formats: bool = (false, parse_bool, [UNTRACKED], "exclude spans when debug-printing compiler state (default: no)"), diff --git a/src/test/ui/proc-macro/debug/dump-debug-span-debug.rs b/src/test/ui/proc-macro/debug/dump-debug-span-debug.rs new file mode 100644 index 0000000000000..fd34eb974c094 --- /dev/null +++ b/src/test/ui/proc-macro/debug/dump-debug-span-debug.rs @@ -0,0 +1,41 @@ +// run-pass +// aux-build:macro-dump-debug.rs +// compile-flags: -Z span-debug + +extern crate macro_dump_debug; +use macro_dump_debug::dump_debug; + +dump_debug! { + ident // ident + r#ident // raw ident + , // alone punct + ==> // joint punct + () // empty group + [_] // nonempty group + + // unsuffixed literals + 0 + 1.0 + "S" + b"B" + r"R" + r##"R"## + br"BR" + br##"BR"## + 'C' + b'B' + + // suffixed literals + 0q + 1.0q + "S"q + b"B"q + r"R"q + r##"R"##q + br"BR"q + br##"BR"##q + 'C'q + b'B'q +} + +fn main() {} diff --git a/src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr b/src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr new file mode 100644 index 0000000000000..163a2c9f44cad --- /dev/null +++ b/src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr @@ -0,0 +1,166 @@ +TokenStream [Ident { ident: "ident", span: $DIR/dump-debug-span-debug.rs:9:5: 9:10 }, Ident { ident: "r#ident", span: $DIR/dump-debug-span-debug.rs:10:5: 10:12 }, Punct { ch: ',', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:11:5: 11:6 }, Punct { ch: '=', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:12:5: 12:7 }, Punct { ch: '=', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:12:5: 12:7 }, Punct { ch: '>', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:12:7: 12:8 }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/dump-debug-span-debug.rs:13:5: 13:7 }, Group { delimiter: Bracket, stream: TokenStream [Ident { ident: "_", span: $DIR/dump-debug-span-debug.rs:14:6: 14:7 }], span: $DIR/dump-debug-span-debug.rs:14:5: 14:8 }, Literal { kind: Integer, symbol: "0", suffix: None, span: $DIR/dump-debug-span-debug.rs:17:5: 17:6 }, Literal { kind: Float, symbol: "1.0", suffix: None, span: $DIR/dump-debug-span-debug.rs:18:5: 18:8 }, Literal { kind: Str, symbol: "S", suffix: None, span: $DIR/dump-debug-span-debug.rs:19:5: 19:8 }, Literal { kind: ByteStr, symbol: "B", suffix: None, span: $DIR/dump-debug-span-debug.rs:20:5: 20:9 }, Literal { kind: StrRaw(0), symbol: "R", suffix: None, span: $DIR/dump-debug-span-debug.rs:21:5: 21:9 }, Literal { kind: StrRaw(2), symbol: "R", suffix: None, span: $DIR/dump-debug-span-debug.rs:22:5: 22:13 }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: None, span: $DIR/dump-debug-span-debug.rs:23:5: 23:11 }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: None, span: $DIR/dump-debug-span-debug.rs:24:5: 24:15 }, Literal { kind: Char, symbol: "C", suffix: None, span: $DIR/dump-debug-span-debug.rs:25:5: 25:8 }, Literal { kind: Byte, symbol: "B", suffix: None, span: $DIR/dump-debug-span-debug.rs:26:5: 26:9 }, Literal { kind: Integer, symbol: "0", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:29:5: 29:7 }, Literal { kind: Float, symbol: "1.0", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:30:5: 30:9 }, Literal { kind: Str, symbol: "S", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:31:5: 31:9 }, Literal { kind: ByteStr, symbol: "B", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:32:5: 32:10 }, Literal { kind: StrRaw(0), symbol: "R", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:33:5: 33:10 }, Literal { kind: StrRaw(2), symbol: "R", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:34:5: 34:14 }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:35:5: 35:12 }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:36:5: 36:16 }, Literal { kind: Char, symbol: "C", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:37:5: 37:9 }, Literal { kind: Byte, symbol: "B", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:38:5: 38:10 }] +TokenStream [ + Ident { + ident: "ident", + span: $DIR/dump-debug-span-debug.rs:9:5: 9:10, + }, + Ident { + ident: "r#ident", + span: $DIR/dump-debug-span-debug.rs:10:5: 10:12, + }, + Punct { + ch: ',', + spacing: Alone, + span: $DIR/dump-debug-span-debug.rs:11:5: 11:6, + }, + Punct { + ch: '=', + spacing: Joint, + span: $DIR/dump-debug-span-debug.rs:12:5: 12:7, + }, + Punct { + ch: '=', + spacing: Joint, + span: $DIR/dump-debug-span-debug.rs:12:5: 12:7, + }, + Punct { + ch: '>', + spacing: Alone, + span: $DIR/dump-debug-span-debug.rs:12:7: 12:8, + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [], + span: $DIR/dump-debug-span-debug.rs:13:5: 13:7, + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "_", + span: $DIR/dump-debug-span-debug.rs:14:6: 14:7, + }, + ], + span: $DIR/dump-debug-span-debug.rs:14:5: 14:8, + }, + Literal { + kind: Integer, + symbol: "0", + suffix: None, + span: $DIR/dump-debug-span-debug.rs:17:5: 17:6, + }, + Literal { + kind: Float, + symbol: "1.0", + suffix: None, + span: $DIR/dump-debug-span-debug.rs:18:5: 18:8, + }, + Literal { + kind: Str, + symbol: "S", + suffix: None, + span: $DIR/dump-debug-span-debug.rs:19:5: 19:8, + }, + Literal { + kind: ByteStr, + symbol: "B", + suffix: None, + span: $DIR/dump-debug-span-debug.rs:20:5: 20:9, + }, + Literal { + kind: StrRaw(0), + symbol: "R", + suffix: None, + span: $DIR/dump-debug-span-debug.rs:21:5: 21:9, + }, + Literal { + kind: StrRaw(2), + symbol: "R", + suffix: None, + span: $DIR/dump-debug-span-debug.rs:22:5: 22:13, + }, + Literal { + kind: ByteStrRaw(0), + symbol: "BR", + suffix: None, + span: $DIR/dump-debug-span-debug.rs:23:5: 23:11, + }, + Literal { + kind: ByteStrRaw(2), + symbol: "BR", + suffix: None, + span: $DIR/dump-debug-span-debug.rs:24:5: 24:15, + }, + Literal { + kind: Char, + symbol: "C", + suffix: None, + span: $DIR/dump-debug-span-debug.rs:25:5: 25:8, + }, + Literal { + kind: Byte, + symbol: "B", + suffix: None, + span: $DIR/dump-debug-span-debug.rs:26:5: 26:9, + }, + Literal { + kind: Integer, + symbol: "0", + suffix: Some("q"), + span: $DIR/dump-debug-span-debug.rs:29:5: 29:7, + }, + Literal { + kind: Float, + symbol: "1.0", + suffix: Some("q"), + span: $DIR/dump-debug-span-debug.rs:30:5: 30:9, + }, + Literal { + kind: Str, + symbol: "S", + suffix: Some("q"), + span: $DIR/dump-debug-span-debug.rs:31:5: 31:9, + }, + Literal { + kind: ByteStr, + symbol: "B", + suffix: Some("q"), + span: $DIR/dump-debug-span-debug.rs:32:5: 32:10, + }, + Literal { + kind: StrRaw(0), + symbol: "R", + suffix: Some("q"), + span: $DIR/dump-debug-span-debug.rs:33:5: 33:10, + }, + Literal { + kind: StrRaw(2), + symbol: "R", + suffix: Some("q"), + span: $DIR/dump-debug-span-debug.rs:34:5: 34:14, + }, + Literal { + kind: ByteStrRaw(0), + symbol: "BR", + suffix: Some("q"), + span: $DIR/dump-debug-span-debug.rs:35:5: 35:12, + }, + Literal { + kind: ByteStrRaw(2), + symbol: "BR", + suffix: Some("q"), + span: $DIR/dump-debug-span-debug.rs:36:5: 36:16, + }, + Literal { + kind: Char, + symbol: "C", + suffix: Some("q"), + span: $DIR/dump-debug-span-debug.rs:37:5: 37:9, + }, + Literal { + kind: Byte, + symbol: "B", + suffix: Some("q"), + span: $DIR/dump-debug-span-debug.rs:38:5: 38:10, + }, +]