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`.