From 76ea56667703ac06689ff1d6fba5d170fa7392a7 Mon Sep 17 00:00:00 2001 From: est31 Date: Mon, 21 Feb 2022 08:27:24 +0100 Subject: [PATCH] Better error if the user tries to do assignment ... else --- compiler/rustc_parse/src/parser/stmt.rs | 10 ++++++++++ src/test/ui/let-else/let-else-destructuring.rs | 18 ++++++++++++++++++ .../ui/let-else/let-else-destructuring.stderr | 17 +++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 src/test/ui/let-else/let-else-destructuring.rs create mode 100644 src/test/ui/let-else/let-else-destructuring.stderr diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 227a9e37dbcb4..965e6a6ca3f27 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -103,6 +103,16 @@ impl<'a> Parser<'a> { } else { self.parse_expr_res(Restrictions::STMT_EXPR, Some(attrs)) }?; + if matches!(e.kind, ExprKind::Assign(..)) && self.eat_keyword(kw::Else) { + let bl = self.parse_block()?; + // Destructuring assignment ... else. + // This is not allowed, but point it out in a nice way. + let mut err = self.struct_span_err( + e.span.to(bl.span), + " ... else { ... } is not allowed", + ); + err.emit(); + } self.mk_stmt(lo.to(e.span), StmtKind::Expr(e)) } else { self.error_outer_attrs(&attrs.take_for_recovery()); diff --git a/src/test/ui/let-else/let-else-destructuring.rs b/src/test/ui/let-else/let-else-destructuring.rs new file mode 100644 index 0000000000000..9a09c414ac80f --- /dev/null +++ b/src/test/ui/let-else/let-else-destructuring.rs @@ -0,0 +1,18 @@ +#![feature(let_else)] +#[derive(Debug)] +enum Foo { + Done, + Nested(Option<&'static Foo>), +} + +fn walk(mut value: &Foo) { + loop { + println!("{:?}", value); + &Foo::Nested(Some(value)) = value else { break }; //~ ERROR invalid left-hand side of assignment + //~^ERROR ... else { ... } is not allowed + } +} + +fn main() { + walk(&Foo::Done); +} diff --git a/src/test/ui/let-else/let-else-destructuring.stderr b/src/test/ui/let-else/let-else-destructuring.stderr new file mode 100644 index 0000000000000..95efb7116829e --- /dev/null +++ b/src/test/ui/let-else/let-else-destructuring.stderr @@ -0,0 +1,17 @@ +error: ... else { ... } is not allowed + --> $DIR/let-else-destructuring.rs:11:9 + | +LL | &Foo::Nested(Some(value)) = value else { break }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0070]: invalid left-hand side of assignment + --> $DIR/let-else-destructuring.rs:11:35 + | +LL | &Foo::Nested(Some(value)) = value else { break }; + | ------------------------- ^ + | | + | cannot assign to this expression + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0070`.