Skip to content

Commit c92d61d

Browse files
authored
Rollup merge of #144409 - GuillaumeGomez:macro-expansion-early-abort, r=oli-obk
Stop compilation early if macro expansion failed Fixes #116180. So there isn't really a type that is central for macro expansion and some errors are actually emitted (because the resolution happens after the expansion I suppose) after the expansion pass (like "not found macro"). Sometimes, errors are only emitted on the second "try" (to improve error output). So I couldn't reach a similar solution than what was done in #133937 and suggested by ````@estebank```` in #116180 (comment). But maybe I missed something? So in the end, I realized that there is method called every time (except one, described below) a macro error is actually emitted: `ExtCtxt::trace_macros_diag`. Considering I updated what it did, I renamed it into `macro_error_and_trace_macros_diag` to better reflect it. There is only one call of `trace_macros_diag` which isn't reporting an error but just used for `macro_trace` feature, so I kept it as is. r? ````@oli-obk````
2 parents 2c395c7 + 2725138 commit c92d61d

29 files changed

+323
-249
lines changed

compiler/rustc_expand/src/base.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,7 @@ pub struct ExtCtxt<'a> {
12241224
pub(super) expanded_inert_attrs: MarkedAttrs,
12251225
/// `-Zmacro-stats` data.
12261226
pub macro_stats: FxHashMap<(Symbol, MacroKind), MacroStat>,
1227+
pub nb_macro_errors: usize,
12271228
}
12281229

12291230
impl<'a> ExtCtxt<'a> {
@@ -1254,6 +1255,7 @@ impl<'a> ExtCtxt<'a> {
12541255
expanded_inert_attrs: MarkedAttrs::new(),
12551256
buffered_early_lint: vec![],
12561257
macro_stats: Default::default(),
1258+
nb_macro_errors: 0,
12571259
}
12581260
}
12591261

@@ -1315,6 +1317,12 @@ impl<'a> ExtCtxt<'a> {
13151317
self.current_expansion.id.expansion_cause()
13161318
}
13171319

1320+
/// This method increases the internal macro errors count and then call `trace_macros_diag`.
1321+
pub fn macro_error_and_trace_macros_diag(&mut self) {
1322+
self.nb_macro_errors += 1;
1323+
self.trace_macros_diag();
1324+
}
1325+
13181326
pub fn trace_macros_diag(&mut self) {
13191327
for (span, notes) in self.expansions.iter() {
13201328
let mut db = self.dcx().create_note(errors::TraceMacro { span: *span });

compiler/rustc_expand/src/expand.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
693693
crate_name: self.cx.ecfg.crate_name,
694694
});
695695

696-
self.cx.trace_macros_diag();
696+
self.cx.macro_error_and_trace_macros_diag();
697697
guar
698698
}
699699

@@ -707,7 +707,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
707707
) -> ErrorGuaranteed {
708708
let guar =
709709
self.cx.dcx().emit_err(WrongFragmentKind { span, kind: kind.name(), name: &mac.path });
710-
self.cx.trace_macros_diag();
710+
self.cx.macro_error_and_trace_macros_diag();
711711
guar
712712
}
713713

@@ -1048,7 +1048,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
10481048
}
10491049
annotate_err_with_kind(&mut err, kind, span);
10501050
let guar = err.emit();
1051-
self.cx.trace_macros_diag();
1051+
self.cx.macro_error_and_trace_macros_diag();
10521052
kind.dummy(span, guar)
10531053
}
10541054
}

compiler/rustc_expand/src/mbe/macro_parser.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ enum EofMatcherPositions {
299299
}
300300

301301
/// Represents the possible results of an attempted parse.
302+
#[derive(Debug)]
302303
pub(crate) enum ParseResult<T, F> {
303304
/// Parsed successfully.
304305
Success(T),

compiler/rustc_expand/src/mbe/macro_rules.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ fn expand_macro<'cx>(
280280
// Retry and emit a better error.
281281
let (span, guar) =
282282
diagnostics::failed_to_match_macro(cx.psess(), sp, def_span, name, arg, rules);
283-
cx.trace_macros_diag();
283+
cx.macro_error_and_trace_macros_diag();
284284
DummyResult::any(span, guar)
285285
}
286286
}

compiler/rustc_interface/src/passes.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,10 @@ fn configure_and_expand(
208208
// Expand macros now!
209209
let krate = sess.time("expand_crate", || ecx.monotonic_expander().expand_crate(krate));
210210

211+
if ecx.nb_macro_errors > 0 {
212+
sess.dcx().abort_if_errors();
213+
}
214+
211215
// The rest is error reporting and stats
212216

213217
sess.psess.buffered_lints.with_lock(|buffered_lints: &mut Vec<BufferedEarlyLint>| {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
trait Marker<const N: usize> {}
2+
struct Example<const N: usize>;
3+
impl<const N: usize> Marker<N> for Example<N> {}
4+
5+
fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
6+
//~^ ERROR: type provided when a constant was expected
7+
//~| ERROR: type provided when a constant was expected
8+
Example::<gimme_a_const!(marker)>
9+
//~^ ERROR: type provided when a constant was expected
10+
}
11+
12+
fn main() {
13+
let _ok = Example::<{
14+
#[macro_export]
15+
macro_rules! gimme_a_const {
16+
($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
17+
//~^ ERROR expected type
18+
//~| ERROR expected type
19+
}
20+
gimme_a_const!(run)
21+
}>;
22+
let _ok = Example::<{gimme_a_const!(marker)}>;
23+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
error: expected type, found `{`
2+
--> $DIR/macro-fail-const.rs:16:27
3+
|
4+
LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
5+
| ----------------------
6+
| |
7+
| this macro call doesn't expand to a type
8+
| in this macro invocation
9+
...
10+
LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
11+
| ^ expected type
12+
|
13+
= note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info)
14+
15+
error: expected type, found `{`
16+
--> $DIR/macro-fail-const.rs:16:27
17+
|
18+
LL | Example::<gimme_a_const!(marker)>
19+
| ----------------------
20+
| |
21+
| this macro call doesn't expand to a type
22+
| in this macro invocation
23+
...
24+
LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
25+
| ^ expected type
26+
|
27+
= note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info)
28+
29+
error[E0747]: type provided when a constant was expected
30+
--> $DIR/macro-fail-const.rs:5:33
31+
|
32+
LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
33+
| ^^^^^^^^^^^^^^^^^^^^^^
34+
35+
error[E0747]: type provided when a constant was expected
36+
--> $DIR/macro-fail-const.rs:5:33
37+
|
38+
LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
39+
| ^^^^^^^^^^^^^^^^^^^^^^
40+
|
41+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
42+
43+
error[E0747]: type provided when a constant was expected
44+
--> $DIR/macro-fail-const.rs:8:13
45+
|
46+
LL | Example::<gimme_a_const!(marker)>
47+
| ^^^^^^^^^^^^^^^^^^^^^^
48+
49+
error: aborting due to 5 previous errors
50+
51+
For more information about this error, try `rustc --explain E0747`.

tests/ui/const-generics/min_const_generics/macro-fail.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@ trait Marker<const N: usize> {}
1212
impl<const N: usize> Marker<N> for Example<N> {}
1313

1414
fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
15-
//~^ ERROR: type provided when a constant was expected
16-
//~| ERROR: type provided when a constant was expected
1715
Example::<gimme_a_const!(marker)>
18-
//~^ ERROR: type provided when a constant was expected
1916
}
2017

2118
fn from_marker(_: impl Marker<{
@@ -35,9 +32,7 @@ fn main() {
3532
}>;
3633

3734
let _fail = Example::<external_macro!()>;
38-
//~^ ERROR: type provided when a constant
3935

4036
let _fail = Example::<gimme_a_const!()>;
41-
//~^ ERROR unexpected end of macro invocation
42-
//~| ERROR: type provided when a constant was expected
37+
//~^ ERROR: unexpected end of macro invocation
4338
}
Lines changed: 5 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: expected type, found `{`
2-
--> $DIR/macro-fail.rs:30:27
2+
--> $DIR/macro-fail.rs:27:27
33
|
44
LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
55
| ----------------------
@@ -13,7 +13,7 @@ LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
1313
= note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info)
1414

1515
error: expected type, found `{`
16-
--> $DIR/macro-fail.rs:30:27
16+
--> $DIR/macro-fail.rs:27:27
1717
|
1818
LL | Example::<gimme_a_const!(marker)>
1919
| ----------------------
@@ -41,7 +41,7 @@ LL | let _fail = Example::<external_macro!()>;
4141
= note: this error originates in the macro `external_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
4242

4343
error: unexpected end of macro invocation
44-
--> $DIR/macro-fail.rs:40:25
44+
--> $DIR/macro-fail.rs:36:25
4545
|
4646
LL | macro_rules! gimme_a_const {
4747
| -------------------------- when calling this macro
@@ -50,43 +50,10 @@ LL | let _fail = Example::<gimme_a_const!()>;
5050
| ^^^^^^^^^^^^^^^^ missing tokens in macro arguments
5151
|
5252
note: while trying to match meta-variable `$rusty:ident`
53-
--> $DIR/macro-fail.rs:30:8
53+
--> $DIR/macro-fail.rs:27:8
5454
|
5555
LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
5656
| ^^^^^^^^^^^^^
5757

58-
error[E0747]: type provided when a constant was expected
59-
--> $DIR/macro-fail.rs:14:33
60-
|
61-
LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
62-
| ^^^^^^^^^^^^^^^^^^^^^^
63-
64-
error[E0747]: type provided when a constant was expected
65-
--> $DIR/macro-fail.rs:14:33
66-
|
67-
LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
68-
| ^^^^^^^^^^^^^^^^^^^^^^
69-
|
70-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
71-
72-
error[E0747]: type provided when a constant was expected
73-
--> $DIR/macro-fail.rs:17:13
74-
|
75-
LL | Example::<gimme_a_const!(marker)>
76-
| ^^^^^^^^^^^^^^^^^^^^^^
77-
78-
error[E0747]: type provided when a constant was expected
79-
--> $DIR/macro-fail.rs:37:25
80-
|
81-
LL | let _fail = Example::<external_macro!()>;
82-
| ^^^^^^^^^^^^^^^^^
83-
84-
error[E0747]: type provided when a constant was expected
85-
--> $DIR/macro-fail.rs:40:25
86-
|
87-
LL | let _fail = Example::<gimme_a_const!()>;
88-
| ^^^^^^^^^^^^^^^^
89-
90-
error: aborting due to 9 previous errors
58+
error: aborting due to 4 previous errors
9159

92-
For more information about this error, try `rustc --explain E0747`.

tests/ui/editions/edition-keywords-2018-2015-parsing.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub fn check_async() {
2626
module::async(); //~ ERROR expected identifier, found keyword `async`
2727
module::r#async(); // OK
2828

29-
let _recovery_witness: () = 0; //~ ERROR mismatched types
29+
let _recovery_witness: () = 0; // not emitted because of the macro parsing error
3030
}
3131

3232
//~? ERROR macro expansion ends with an incomplete expression

0 commit comments

Comments
 (0)