diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-03-17 12:12:57 +0100 |
|---|---|---|
| committer | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-03-24 06:28:56 +0100 |
| commit | df9cec2df4da27b8a6d1f3ec031392290ff279d1 (patch) | |
| tree | a473a16a2a90919163cea5e0b59e4a02b9b4088c /src | |
| parent | ad26401dc133aa6db6aaa8631aa9bf54d81947f6 (diff) | |
| download | rust-df9cec2df4da27b8a6d1f3ec031392290ff279d1.tar.gz rust-df9cec2df4da27b8a6d1f3ec031392290ff279d1.zip | |
mbe::transcribe: defatalize errors.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_expand/base.rs | 16 | ||||
| -rw-r--r-- | src/librustc_expand/mbe/macro_rules.rs | 8 | ||||
| -rw-r--r-- | src/librustc_expand/mbe/transcribe.rs | 27 | ||||
| -rw-r--r-- | src/test/ui/macros/issue-61033-1.rs | 3 | ||||
| -rw-r--r-- | src/test/ui/macros/issue-61033-1.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/macros/issue-61033-2.rs | 8 | ||||
| -rw-r--r-- | src/test/ui/macros/issue-61033-2.stderr | 15 | ||||
| -rw-r--r-- | src/test/ui/parser/macro/macro-repeat.rs | 9 | ||||
| -rw-r--r-- | src/test/ui/parser/macro/macro-repeat.stderr | 8 |
9 files changed, 68 insertions, 37 deletions
diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs index 0ecbd84cb6a..518a214b4a5 100644 --- a/src/librustc_expand/base.rs +++ b/src/librustc_expand/base.rs @@ -1018,22 +1018,6 @@ impl<'a> ExtCtxt<'a> { self.parse_sess.span_diagnostic.struct_span_err(sp, msg) } - /// Emit `msg` attached to `sp`, and stop compilation immediately. - /// - /// `span_err` should be strongly preferred where-ever possible: - /// this should *only* be used when: - /// - /// - continuing has a high risk of flow-on errors (e.g., errors in - /// declaring a macro would cause all uses of that macro to - /// complain about "undefined macro"), or - /// - there is literally nothing else that can be done (however, - /// in most cases one can construct a dummy expression/item to - /// substitute; we never hit resolve/type-checking so the dummy - /// value doesn't have to match anything) - pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! { - self.parse_sess.span_diagnostic.span_fatal(sp, msg).raise(); - } - /// Emit `msg` attached to `sp`, without immediately stopping /// compilation. /// diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs index 9d6f5e75faa..d4fe382b84b 100644 --- a/src/librustc_expand/mbe/macro_rules.rs +++ b/src/librustc_expand/mbe/macro_rules.rs @@ -255,7 +255,13 @@ fn generic_extension<'cx>( let rhs_spans = rhs.iter().map(|t| t.span()).collect::<Vec<_>>(); // rhs has holes ( `$id` and `$(...)` that need filled) - let mut tts = transcribe(cx, &named_matches, rhs, transparency); + let mut tts = match transcribe(cx, &named_matches, rhs, transparency) { + Ok(tts) => tts, + Err(mut err) => { + err.emit(); + return DummyResult::any(arm_span); + } + }; // Replace all the tokens for the corresponding positions in the macro, to maintain // proper positions in error reporting, while maintaining the macro_backtrace. diff --git a/src/librustc_expand/mbe/transcribe.rs b/src/librustc_expand/mbe/transcribe.rs index 1b1093c9529..e2d3d5c4d64 100644 --- a/src/librustc_expand/mbe/transcribe.rs +++ b/src/librustc_expand/mbe/transcribe.rs @@ -8,7 +8,7 @@ use rustc_ast::token::{self, NtTT, Token}; use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; -use rustc_errors::pluralize; +use rustc_errors::{pluralize, PResult}; use rustc_span::hygiene::{ExpnId, Transparency}; use rustc_span::symbol::MacroRulesNormalizedIdent; use rustc_span::Span; @@ -80,15 +80,15 @@ impl Iterator for Frame { /// `transcribe` would return a `TokenStream` containing `println!("{}", stringify!(bar));`. /// /// Along the way, we do some additional error checking. -pub(super) fn transcribe( - cx: &ExtCtxt<'_>, +pub(super) fn transcribe<'a>( + cx: &ExtCtxt<'a>, interp: &FxHashMap<MacroRulesNormalizedIdent, NamedMatch>, src: Vec<mbe::TokenTree>, transparency: Transparency, -) -> TokenStream { +) -> PResult<'a, TokenStream> { // Nothing for us to transcribe... if src.is_empty() { - return TokenStream::default(); + return Ok(TokenStream::default()); } // We descend into the RHS (`src`), expanding things as we go. This stack contains the things @@ -152,7 +152,7 @@ pub(super) fn transcribe( Frame::Delimited { forest, span, .. } => { if result_stack.is_empty() { // No results left to compute! We are back at the top-level. - return TokenStream::new(result); + return Ok(TokenStream::new(result)); } // Step back into the parent Delimited. @@ -173,11 +173,11 @@ pub(super) fn transcribe( seq @ mbe::TokenTree::Sequence(..) => { match lockstep_iter_size(&seq, interp, &repeats) { LockstepIterSize::Unconstrained => { - cx.span_fatal( + return Err(cx.struct_span_err( seq.span(), /* blame macro writer */ "attempted to repeat an expression containing no syntax variables \ matched as repeating at this depth", - ); + )); } LockstepIterSize::Contradiction(ref msg) => { @@ -185,7 +185,7 @@ pub(super) fn transcribe( // happens when two meta-variables are used in the same repetition in a // sequence, but they come from different sequence matchers and repeat // different amounts. - cx.span_fatal(seq.span(), &msg[..]); + return Err(cx.struct_span_err(seq.span(), &msg[..])); } LockstepIterSize::Constraint(len, _) => { @@ -203,7 +203,10 @@ pub(super) fn transcribe( // FIXME: this really ought to be caught at macro definition // time... It happens when the Kleene operator in the matcher and // the body for the same meta-variable do not match. - cx.span_fatal(sp.entire(), "this must repeat at least once"); + return Err(cx.struct_span_err( + sp.entire(), + "this must repeat at least once", + )); } } else { // 0 is the initial counter (we have done 0 repretitions so far). `len` @@ -242,10 +245,10 @@ pub(super) fn transcribe( } } else { // We were unable to descend far enough. This is an error. - cx.span_fatal( + return Err(cx.struct_span_err( sp, /* blame the macro writer */ &format!("variable '{}' is still repeating at this depth", ident), - ); + )); } } else { // If we aren't able to match the meta-var, we push it back into the result but diff --git a/src/test/ui/macros/issue-61033-1.rs b/src/test/ui/macros/issue-61033-1.rs index 8f85dec017f..18df3f6ee94 100644 --- a/src/test/ui/macros/issue-61033-1.rs +++ b/src/test/ui/macros/issue-61033-1.rs @@ -1,9 +1,10 @@ // Regression test for issue #61033. macro_rules! test1 { - ($x:ident, $($tt:tt)*) => { $($tt)+ } //~ERROR this must repeat at least once + ($x:ident, $($tt:tt)*) => { $($tt)+ } //~ ERROR this must repeat at least once } fn main() { test1!(x,); + let _recovery_witness: () = 0; //~ ERROR mismatched types } diff --git a/src/test/ui/macros/issue-61033-1.stderr b/src/test/ui/macros/issue-61033-1.stderr index f3c68f4928d..18205c3436b 100644 --- a/src/test/ui/macros/issue-61033-1.stderr +++ b/src/test/ui/macros/issue-61033-1.stderr @@ -4,5 +4,14 @@ error: this must repeat at least once LL | ($x:ident, $($tt:tt)*) => { $($tt)+ } | ^^^^^ -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/issue-61033-1.rs:9:33 + | +LL | let _recovery_witness: () = 0; + | -- ^ expected `()`, found integer + | | + | expected due to this + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/macros/issue-61033-2.rs b/src/test/ui/macros/issue-61033-2.rs index 0799be10b96..1760ba1584d 100644 --- a/src/test/ui/macros/issue-61033-2.rs +++ b/src/test/ui/macros/issue-61033-2.rs @@ -5,7 +5,9 @@ macro_rules! test2 { $(* $id1:ident)* $(+ $id2:ident)* ) => { - $( //~ERROR meta-variable `id1` repeats 2 times + $( + //~^ ERROR meta-variable `id1` repeats 2 times + //~| ERROR meta-variable `id1` repeats 2 times $id1 + $id2 // $id1 and $id2 may repeat different numbers of times )* } @@ -16,4 +18,8 @@ fn main() { * a * b + a + b + c } + test2! { + * a * b + + a + b + c + d + } } diff --git a/src/test/ui/macros/issue-61033-2.stderr b/src/test/ui/macros/issue-61033-2.stderr index bf502919cf7..cdfe7934a0c 100644 --- a/src/test/ui/macros/issue-61033-2.stderr +++ b/src/test/ui/macros/issue-61033-2.stderr @@ -3,9 +3,22 @@ error: meta-variable `id1` repeats 2 times, but `id2` repeats 3 times | LL | $( | __________^ +LL | | +LL | | LL | | $id1 + $id2 // $id1 and $id2 may repeat different numbers of times LL | | )* | |_________^ -error: aborting due to previous error +error: meta-variable `id1` repeats 2 times, but `id2` repeats 4 times + --> $DIR/issue-61033-2.rs:8:10 + | +LL | $( + | __________^ +LL | | +LL | | +LL | | $id1 + $id2 // $id1 and $id2 may repeat different numbers of times +LL | | )* + | |_________^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/macro/macro-repeat.rs b/src/test/ui/parser/macro/macro-repeat.rs index 580a1daacbf..3ffbea217e7 100644 --- a/src/test/ui/parser/macro/macro-repeat.rs +++ b/src/test/ui/parser/macro/macro-repeat.rs @@ -1,9 +1,12 @@ macro_rules! mac { - ( $($v:tt)* ) => ( - $v //~ ERROR still repeating at this depth - ) + ( $($v:tt)* ) => { + $v + //~^ ERROR still repeating at this depth + //~| ERROR still repeating at this depth + }; } fn main() { mac!(0); + mac!(1); } diff --git a/src/test/ui/parser/macro/macro-repeat.stderr b/src/test/ui/parser/macro/macro-repeat.stderr index c86684de744..63554b197b9 100644 --- a/src/test/ui/parser/macro/macro-repeat.stderr +++ b/src/test/ui/parser/macro/macro-repeat.stderr @@ -4,5 +4,11 @@ error: variable 'v' is still repeating at this depth LL | $v | ^^ -error: aborting due to previous error +error: variable 'v' is still repeating at this depth + --> $DIR/macro-repeat.rs:3:9 + | +LL | $v + | ^^ + +error: aborting due to 2 previous errors |
