about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_builtin_macros/src/cfg_eval.rs4
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs3
-rw-r--r--tests/ui/cfg/cfg-stmt-recovery.rs13
-rw-r--r--tests/ui/cfg/cfg-stmt-recovery.stderr20
4 files changed, 38 insertions, 2 deletions
diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs
index 750f1fe121f..ed91cea4ae2 100644
--- a/compiler/rustc_builtin_macros/src/cfg_eval.rs
+++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs
@@ -166,7 +166,9 @@ impl CfgEval<'_, '_> {
                     ))
                 },
                 Annotatable::Stmt(_) => |parser| {
-                    Ok(Annotatable::Stmt(P(parser.parse_stmt(ForceCollect::Yes)?.unwrap())))
+                    Ok(Annotatable::Stmt(P(parser
+                        .parse_stmt_without_recovery(false, ForceCollect::Yes)?
+                        .unwrap())))
                 },
                 Annotatable::Expr(_) => {
                     |parser| Ok(Annotatable::Expr(parser.parse_expr_force_collect()?))
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index fbe5b88c49e..e883d6dbf61 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -37,7 +37,8 @@ impl<'a> Parser<'a> {
 
     /// If `force_collect` is [`ForceCollect::Yes`], forces collection of tokens regardless of whether
     /// or not we have attributes
-    pub(crate) fn parse_stmt_without_recovery(
+    // Public for `cfg_eval` macro expansion.
+    pub fn parse_stmt_without_recovery(
         &mut self,
         capture_semi: bool,
         force_collect: ForceCollect,
diff --git a/tests/ui/cfg/cfg-stmt-recovery.rs b/tests/ui/cfg/cfg-stmt-recovery.rs
new file mode 100644
index 00000000000..2e0839d2a15
--- /dev/null
+++ b/tests/ui/cfg/cfg-stmt-recovery.rs
@@ -0,0 +1,13 @@
+// Verify that we do not ICE when failing to parse a statement in `cfg_eval`.
+
+#![feature(cfg_eval)]
+#![feature(stmt_expr_attributes)]
+
+#[cfg_eval]
+fn main() {
+    #[cfg_eval]
+    let _ = #[cfg(FALSE)] 0;
+    //~^ ERROR removing an expression is not supported in this position
+    //~| ERROR expected expression, found `;`
+    //~| ERROR removing an expression is not supported in this position
+}
diff --git a/tests/ui/cfg/cfg-stmt-recovery.stderr b/tests/ui/cfg/cfg-stmt-recovery.stderr
new file mode 100644
index 00000000000..cb15e21fac6
--- /dev/null
+++ b/tests/ui/cfg/cfg-stmt-recovery.stderr
@@ -0,0 +1,20 @@
+error: removing an expression is not supported in this position
+  --> $DIR/cfg-stmt-recovery.rs:9:13
+   |
+LL |     let _ = #[cfg(FALSE)] 0;
+   |             ^^^^^^^^^^^^^
+
+error: expected expression, found `;`
+  --> $DIR/cfg-stmt-recovery.rs:9:28
+   |
+LL |     let _ = #[cfg(FALSE)] 0;
+   |                            ^ expected expression
+
+error: removing an expression is not supported in this position
+  --> $DIR/cfg-stmt-recovery.rs:9:13
+   |
+LL |     let _ = #[cfg(FALSE)] 0;
+   |             ^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+