Skip to content

Commit 6f6faa7

Browse files
author
Maximilian Azendorf
committed
Fix diagnostics for non-exhaustive destructuring assignments (#157553)
1 parent 43a4909 commit 6f6faa7

5 files changed

Lines changed: 42 additions & 9 deletions

File tree

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,16 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
436436
assert!(self.let_source != LetSource::None);
437437
let scrut = scrutinee.map(|id| &self.thir[id]);
438438
if let LetSource::PlainLet = self.let_source {
439-
self.check_binding_is_irrefutable(pat, "local binding", scrut, Some(span));
439+
// `lhs = rhs` destructuring assignments are lowered to a `let` tagged
440+
// `AssignDesugar`; report them as assignments, not `let` bindings (#157553).
441+
if let hir::Node::LetStmt(&hir::LetStmt {
442+
source: hir::LocalSource::AssignDesugar, ..
443+
}) = self.tcx.hir_node(self.hir_source)
444+
{
445+
self.check_binding_is_irrefutable(pat, "assignment", scrut, None);
446+
} else {
447+
self.check_binding_is_irrefutable(pat, "local binding", scrut, Some(span));
448+
}
440449
} else if let Ok(Irrefutable) = self.is_let_irrefutable(pat, scrut) {
441450
if span.from_expansion() {
442451
self.lint_single_let(span, None, None);
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
fn main() {
22
None = Some(3);
3-
//~^ ERROR refutable pattern in local binding
3+
//~^ ERROR refutable pattern in assignment
44
}

tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
1-
error[E0005]: refutable pattern in local binding
1+
error[E0005]: refutable pattern in assignment
22
--> $DIR/non-exhaustive-destructure.rs:2:5
33
|
44
LL | None = Some(3);
55
| ^^^^ pattern `Some(_)` not covered
66
|
7-
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
8-
= note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
97
= note: the matched value is of type `Option<i32>`
10-
help: you might want to use `if let` to ignore the variant that isn't matched
11-
|
12-
LL | if None = Some(3) { todo!() };
13-
| ++ +++++++++++
148

159
error: aborting due to 1 previous error
1610

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Regression test for <https://github.com/rust-lang/rust/issues/157553>.
2+
3+
enum Foo {
4+
One,
5+
Two,
6+
}
7+
8+
fn main() {
9+
Foo::One = Foo::One;
10+
//~^ ERROR refutable pattern in assignment
11+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0005]: refutable pattern in assignment
2+
--> $DIR/refutable-enum-assignment.rs:9:5
3+
|
4+
LL | Foo::One = Foo::One;
5+
| ^^^^^^^^ pattern `Foo::Two` not covered
6+
|
7+
note: `Foo` defined here
8+
--> $DIR/refutable-enum-assignment.rs:3:6
9+
|
10+
LL | enum Foo {
11+
| ^^^
12+
LL | One,
13+
LL | Two,
14+
| --- not covered
15+
= note: the matched value is of type `Foo`
16+
17+
error: aborting due to 1 previous error
18+
19+
For more information about this error, try `rustc --explain E0005`.

0 commit comments

Comments
 (0)