about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2020-03-17 12:12:57 +0100
committerMazdak Farrokhzad <twingoow@gmail.com>2020-03-24 06:28:56 +0100
commitdf9cec2df4da27b8a6d1f3ec031392290ff279d1 (patch)
treea473a16a2a90919163cea5e0b59e4a02b9b4088c /src
parentad26401dc133aa6db6aaa8631aa9bf54d81947f6 (diff)
downloadrust-df9cec2df4da27b8a6d1f3ec031392290ff279d1.tar.gz
rust-df9cec2df4da27b8a6d1f3ec031392290ff279d1.zip
mbe::transcribe: defatalize errors.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_expand/base.rs16
-rw-r--r--src/librustc_expand/mbe/macro_rules.rs8
-rw-r--r--src/librustc_expand/mbe/transcribe.rs27
-rw-r--r--src/test/ui/macros/issue-61033-1.rs3
-rw-r--r--src/test/ui/macros/issue-61033-1.stderr11
-rw-r--r--src/test/ui/macros/issue-61033-2.rs8
-rw-r--r--src/test/ui/macros/issue-61033-2.stderr15
-rw-r--r--src/test/ui/parser/macro/macro-repeat.rs9
-rw-r--r--src/test/ui/parser/macro/macro-repeat.stderr8
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