Skip to content

Commit 8954b16

Browse files
committed
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 ```
2 parents f03e067 + d4b8e99 commit 8954b16

File tree

4 files changed

+144
-63
lines changed

4 files changed

+144
-63
lines changed

src/librustc_errors/emitter.rs

+49-53
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,11 @@ impl Emitter for EmitterWriter {
6464
}
6565
}
6666

67-
if !db.handler.flags.external_macro_backtrace {
68-
self.fix_multispans_in_std_macros(&mut primary_span, &mut children);
69-
}
67+
self.fix_multispans_in_std_macros(&mut primary_span,
68+
&mut children,
69+
db.handler.flags.external_macro_backtrace);
70+
7071
self.emit_messages_default(&db.level,
71-
db.handler.flags.external_macro_backtrace,
7272
&db.styled_message(),
7373
&db.code,
7474
&primary_span,
@@ -726,7 +726,9 @@ impl EmitterWriter {
726726
// This "fixes" MultiSpans that contain Spans that are pointing to locations inside of
727727
// <*macros>. Since these locations are often difficult to read, we move these Spans from
728728
// <*macros> to their corresponding use site.
729-
fn fix_multispan_in_std_macros(&mut self, span: &mut MultiSpan) -> bool {
729+
fn fix_multispan_in_std_macros(&mut self,
730+
span: &mut MultiSpan,
731+
always_backtrace: bool) -> bool {
730732
let mut spans_updated = false;
731733

732734
if let Some(ref cm) = self.cm {
@@ -739,22 +741,45 @@ impl EmitterWriter {
739741
continue;
740742
}
741743
let call_sp = cm.call_span_if_macro(*sp);
742-
if call_sp != *sp {
743-
before_after.push((sp.clone(), call_sp));
744+
if call_sp != *sp && !always_backtrace {
745+
before_after.push((*sp, call_sp));
744746
}
745-
for trace in sp.macro_backtrace().iter().rev() {
747+
let backtrace_len = sp.macro_backtrace().len();
748+
for (i, trace) in sp.macro_backtrace().iter().rev().enumerate() {
746749
// Only show macro locations that are local
747750
// and display them like a span_note
748751
if let Some(def_site) = trace.def_site_span {
749752
if def_site == DUMMY_SP {
750753
continue;
751754
}
755+
if always_backtrace {
756+
new_labels.push((def_site,
757+
format!("in this expansion of `{}`{}",
758+
trace.macro_decl_name,
759+
if backtrace_len > 2 {
760+
// if backtrace_len == 1 it'll be pointed
761+
// at by "in this macro invocation"
762+
format!(" (#{})", i + 1)
763+
} else {
764+
"".to_string()
765+
})));
766+
}
752767
// Check to make sure we're not in any <*macros>
753768
if !cm.span_to_filename(def_site).contains("macros>") &&
754-
!trace.macro_decl_name.starts_with("#[") {
769+
!trace.macro_decl_name.starts_with("#[") ||
770+
always_backtrace {
755771
new_labels.push((trace.call_site,
756-
"in this macro invocation".to_string()));
757-
break;
772+
format!("in this macro invocation{}",
773+
if backtrace_len > 2 && always_backtrace {
774+
// only specify order when the macro
775+
// backtrace is multiple levels deep
776+
format!(" (#{})", i + 1)
777+
} else {
778+
"".to_string()
779+
})));
780+
if !always_backtrace {
781+
break;
782+
}
758783
}
759784
}
760785
}
@@ -766,7 +791,9 @@ impl EmitterWriter {
766791
if sp_label.span == DUMMY_SP {
767792
continue;
768793
}
769-
if cm.span_to_filename(sp_label.span.clone()).contains("macros>") {
794+
if cm.span_to_filename(sp_label.span.clone()).contains("macros>") &&
795+
!always_backtrace
796+
{
770797
let v = sp_label.span.macro_backtrace();
771798
if let Some(use_site) = v.last() {
772799
before_after.push((sp_label.span.clone(), use_site.call_site.clone()));
@@ -788,18 +815,19 @@ impl EmitterWriter {
788815
// will change the span to point at the use site.
789816
fn fix_multispans_in_std_macros(&mut self,
790817
span: &mut MultiSpan,
791-
children: &mut Vec<SubDiagnostic>) {
792-
let mut spans_updated = self.fix_multispan_in_std_macros(span);
818+
children: &mut Vec<SubDiagnostic>,
819+
backtrace: bool) {
820+
let mut spans_updated = self.fix_multispan_in_std_macros(span, backtrace);
793821
for child in children.iter_mut() {
794-
spans_updated |= self.fix_multispan_in_std_macros(&mut child.span);
822+
spans_updated |= self.fix_multispan_in_std_macros(&mut child.span, backtrace);
795823
}
796824
if spans_updated {
797825
children.push(SubDiagnostic {
798826
level: Level::Note,
799827
message: vec![
800-
(["this error originates in a macro outside of the current crate",
801-
"(in Nightly builds, run with -Z external-macro-backtrace for more info)"]
802-
.join(" "),
828+
("this error originates in a macro outside of the current crate \
829+
(in Nightly builds, run with -Z external-macro-backtrace \
830+
for more info)".to_string(),
803831
Style::NoStyle),
804832
],
805833
span: MultiSpan::new(),
@@ -861,7 +889,7 @@ impl EmitterWriter {
861889
// ("see?", Style::Highlight),
862890
// ];
863891
//
864-
// the expected output on a note is (* surround the highlighted text)
892+
// the expected output on a note is (* surround the highlighted text)
865893
//
866894
// = note: highlighted multiline
867895
// string to
@@ -889,7 +917,6 @@ impl EmitterWriter {
889917
msg: &Vec<(String, Style)>,
890918
code: &Option<DiagnosticId>,
891919
level: &Level,
892-
external_macro_backtrace: bool,
893920
max_line_num_len: usize,
894921
is_secondary: bool)
895922
-> io::Result<()> {
@@ -1087,18 +1114,13 @@ impl EmitterWriter {
10871114
}
10881115
}
10891116

1090-
if external_macro_backtrace {
1091-
if let Some(ref primary_span) = msp.primary_span().as_ref() {
1092-
self.render_macro_backtrace_old_school(primary_span, &mut buffer)?;
1093-
}
1094-
}
1095-
10961117
// final step: take our styled buffer, render it, then output it
10971118
emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?;
10981119

10991120
Ok(())
11001121

11011122
}
1123+
11021124
fn emit_suggestion_default(&mut self,
11031125
suggestion: &CodeSuggestion,
11041126
level: &Level,
@@ -1182,9 +1204,9 @@ impl EmitterWriter {
11821204
}
11831205
Ok(())
11841206
}
1207+
11851208
fn emit_messages_default(&mut self,
11861209
level: &Level,
1187-
external_macro_backtrace: bool,
11881210
message: &Vec<(String, Style)>,
11891211
code: &Option<DiagnosticId>,
11901212
span: &MultiSpan,
@@ -1197,7 +1219,6 @@ impl EmitterWriter {
11971219
message,
11981220
code,
11991221
level,
1200-
external_macro_backtrace,
12011222
max_line_num_len,
12021223
false) {
12031224
Ok(()) => {
@@ -1219,7 +1240,6 @@ impl EmitterWriter {
12191240
&child.styled_message(),
12201241
&None,
12211242
&child.level,
1222-
external_macro_backtrace,
12231243
max_line_num_len,
12241244
true) {
12251245
Err(e) => panic!("failed to emit error: {}", e),
@@ -1248,30 +1268,6 @@ impl EmitterWriter {
12481268
}
12491269
}
12501270
}
1251-
1252-
fn render_macro_backtrace_old_school(&self,
1253-
sp: &Span,
1254-
buffer: &mut StyledBuffer) -> io::Result<()> {
1255-
if let Some(ref cm) = self.cm {
1256-
for trace in sp.macro_backtrace().iter().rev() {
1257-
let line_offset = buffer.num_lines();
1258-
1259-
let mut diag_string =
1260-
format!("in this expansion of {}", trace.macro_decl_name);
1261-
if let Some(def_site_span) = trace.def_site_span {
1262-
diag_string.push_str(
1263-
&format!(" (defined in {})",
1264-
cm.span_to_filename(def_site_span)));
1265-
}
1266-
let snippet = cm.span_to_string(trace.call_site);
1267-
buffer.append(line_offset, &format!("{} ", snippet), Style::NoStyle);
1268-
buffer.append(line_offset, "note", Style::Level(Level::Note));
1269-
buffer.append(line_offset, ": ", Style::NoStyle);
1270-
buffer.append(line_offset, &diag_string, Style::OldSchoolNoteText);
1271-
}
1272-
}
1273-
Ok(())
1274-
}
12751271
}
12761272

12771273
fn draw_col_separator(buffer: &mut StyledBuffer, line: usize, col: usize) {

src/test/ui/macro_backtrace/auxiliary/ping.rs

+21
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,24 @@ macro_rules! ping {
1818
}
1919
}
2020

21+
#[macro_export]
22+
macro_rules! deep {
23+
() => {
24+
foo!();
25+
}
26+
}
27+
28+
#[macro_export]
29+
macro_rules! foo {
30+
() => {
31+
bar!();
32+
}
33+
}
34+
35+
#[macro_export]
36+
macro_rules! bar {
37+
() => {
38+
ping!();
39+
}
40+
}
41+

src/test/ui/macro_backtrace/main.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,14 @@
1616

1717
// a local macro
1818
macro_rules! pong {
19-
() => { syntax error }; //~ ERROR expected one of
20-
//~^ ERROR expected one of
19+
() => { syntax error };
2120
}
21+
//~^^ ERROR expected one of
22+
//~| ERROR expected one of
23+
//~| ERROR expected one of
2224

2325
fn main() {
2426
pong!();
2527
ping!();
28+
deep!();
2629
}
+69-8
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,78 @@
11
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error`
22
--> $DIR/main.rs:19:20
33
|
4-
19 | () => { syntax error }; //~ ERROR expected one of
5-
| ^^^^^ expected one of 8 possible tokens here
6-
$DIR/main.rs:24:5: 24:13 note: in this expansion of pong! (defined in $DIR/main.rs)
4+
18 | / macro_rules! pong {
5+
19 | | () => { syntax error };
6+
| | ^^^^^ expected one of 8 possible tokens here
7+
20 | | }
8+
| |_- in this expansion of `pong!`
9+
...
10+
26 | pong!();
11+
| -------- in this macro invocation
712

813
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error`
914
--> $DIR/main.rs:19:20
1015
|
11-
19 | () => { syntax error }; //~ ERROR expected one of
12-
| ^^^^^ expected one of 8 possible tokens here
13-
$DIR/main.rs:25:5: 25:13 note: in this expansion of ping! (defined in <ping macros>)
14-
<ping macros>:1:11: 1:24 note: in this expansion of pong! (defined in $DIR/main.rs)
16+
18 | / macro_rules! pong {
17+
19 | | () => { syntax error };
18+
| | ^^^^^ expected one of 8 possible tokens here
19+
20 | | }
20+
| |_- in this expansion of `pong!`
21+
...
22+
27 | ping!();
23+
| -------- in this macro invocation
24+
|
25+
::: <ping macros>
26+
|
27+
1 | ( ) => { pong ! ( ) ; }
28+
| -------------------------
29+
| | |
30+
| | in this macro invocation
31+
| in this expansion of `ping!`
32+
33+
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error`
34+
--> $DIR/main.rs:19:20
35+
|
36+
18 | / macro_rules! pong {
37+
19 | | () => { syntax error };
38+
| | ^^^^^ expected one of 8 possible tokens here
39+
20 | | }
40+
| |_- in this expansion of `pong!` (#5)
41+
...
42+
28 | deep!();
43+
| -------- in this macro invocation (#1)
44+
|
45+
::: <deep macros>
46+
|
47+
1 | ( ) => { foo ! ( ) ; }
48+
| ------------------------
49+
| | |
50+
| | in this macro invocation (#2)
51+
| in this expansion of `deep!` (#1)
52+
|
53+
::: <foo macros>
54+
|
55+
1 | ( ) => { bar ! ( ) ; }
56+
| ------------------------
57+
| | |
58+
| | in this macro invocation (#3)
59+
| in this expansion of `foo!` (#2)
60+
|
61+
::: <bar macros>
62+
|
63+
1 | ( ) => { ping ! ( ) ; }
64+
| -------------------------
65+
| | |
66+
| | in this macro invocation (#4)
67+
| in this expansion of `bar!` (#3)
68+
|
69+
::: <ping macros>
70+
|
71+
1 | ( ) => { pong ! ( ) ; }
72+
| -------------------------
73+
| | |
74+
| | in this macro invocation (#5)
75+
| in this expansion of `ping!` (#4)
1576

16-
error: aborting due to 2 previous errors
77+
error: aborting due to 3 previous errors
1778

0 commit comments

Comments
 (0)