Rollup merge of #118759 - compiler-errors:bare-unit-structs, r=petrochenkov
Support bare unit structs in destructuring assignments We should be allowed to use destructuring assignments on *bare* unit structs, not just unit structs that are located within other pattern constructors. Fixes #118753 r? petrochenkov since you reviewed #95380, reassign if you're busy or don't want to review this.
This commit is contained in:
commit
dbc6ec6636
9 changed files with 42 additions and 24 deletions
|
@ -1222,6 +1222,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
| ExprKind::Struct(..)
|
| ExprKind::Struct(..)
|
||||||
| ExprKind::Tup(..)
|
| ExprKind::Tup(..)
|
||||||
| ExprKind::Underscore => false,
|
| ExprKind::Underscore => false,
|
||||||
|
// Check for unit struct constructor.
|
||||||
|
ExprKind::Path(..) => lower_ctx.extract_unit_struct_path(lhs).is_none(),
|
||||||
// Check for tuple struct constructor.
|
// Check for tuple struct constructor.
|
||||||
ExprKind::Call(callee, ..) => lower_ctx.extract_tuple_struct_path(callee).is_none(),
|
ExprKind::Call(callee, ..) => lower_ctx.extract_tuple_struct_path(callee).is_none(),
|
||||||
ExprKind::Paren(e) => {
|
ExprKind::Paren(e) => {
|
||||||
|
|
|
@ -4,6 +4,4 @@ fn main() {
|
||||||
(1, 2) = (3, 4);
|
(1, 2) = (3, 4);
|
||||||
//~^ ERROR invalid left-hand side of assignment
|
//~^ ERROR invalid left-hand side of assignment
|
||||||
//~| ERROR invalid left-hand side of assignment
|
//~| ERROR invalid left-hand side of assignment
|
||||||
|
|
||||||
None = Some(3); //~ ERROR invalid left-hand side of assignment
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,15 +30,7 @@ LL | (1, 2) = (3, 4);
|
||||||
| |
|
| |
|
||||||
| cannot assign to this expression
|
| cannot assign to this expression
|
||||||
|
|
||||||
error[E0070]: invalid left-hand side of assignment
|
error: aborting due to 4 previous errors
|
||||||
--> $DIR/bad-expr-lhs.rs:8:10
|
|
||||||
|
|
|
||||||
LL | None = Some(3);
|
|
||||||
| ---- ^
|
|
||||||
| |
|
|
||||||
| cannot assign to this expression
|
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0067, E0070.
|
Some errors have detailed explanations: E0067, E0070.
|
||||||
For more information about an error, try `rustc --explain E0067`.
|
For more information about an error, try `rustc --explain E0067`.
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
fn main() {
|
||||||
|
None = Some(3);
|
||||||
|
//~^ ERROR refutable pattern in local binding
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
error[E0005]: refutable pattern in local binding
|
||||||
|
--> $DIR/non-exhaustive-destructure.rs:2:5
|
||||||
|
|
|
||||||
|
LL | None = Some(3);
|
||||||
|
| ^^^^ pattern `Some(_)` not covered
|
||||||
|
|
|
||||||
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
|
||||||
|
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
|
||||||
|
= note: the matched value is of type `Option<i32>`
|
||||||
|
help: you might want to use `if let` to ignore the variant that isn't matched
|
||||||
|
|
|
||||||
|
LL | if None = Some(3) { todo!() };
|
||||||
|
| ++ +++++++++++
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0005`.
|
|
@ -11,17 +11,22 @@ type A = E;
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut a;
|
let mut a;
|
||||||
|
|
||||||
|
S = S;
|
||||||
(S, a) = (S, ());
|
(S, a) = (S, ());
|
||||||
|
|
||||||
|
E::V = E::V;
|
||||||
(E::V, a) = (E::V, ());
|
(E::V, a) = (E::V, ());
|
||||||
|
|
||||||
|
<E>::V = E::V;
|
||||||
(<E>::V, a) = (E::V, ());
|
(<E>::V, a) = (E::V, ());
|
||||||
|
A::V = A::V;
|
||||||
(A::V, a) = (E::V, ());
|
(A::V, a) = (E::V, ());
|
||||||
}
|
}
|
||||||
|
|
||||||
impl S {
|
impl S {
|
||||||
fn check() {
|
fn check() {
|
||||||
let a;
|
let a;
|
||||||
|
Self = S;
|
||||||
(Self, a) = (S, ());
|
(Self, a) = (S, ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +34,7 @@ impl S {
|
||||||
impl E {
|
impl E {
|
||||||
fn check() {
|
fn check() {
|
||||||
let a;
|
let a;
|
||||||
|
Self::V = E::V;
|
||||||
(Self::V, a) = (E::V, ());
|
(Self::V, a) = (E::V, ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,14 +26,10 @@ error[E0308]: mismatched types
|
||||||
LL | if None = x { }
|
LL | if None = x { }
|
||||||
| ^^^^^^^^ expected `bool`, found `()`
|
| ^^^^^^^^ expected `bool`, found `()`
|
||||||
|
|
|
|
||||||
help: you might have meant to use pattern matching
|
help: consider adding `let`
|
||||||
|
|
|
|
||||||
LL | if let None = x { }
|
LL | if let None = x { }
|
||||||
| +++
|
| +++
|
||||||
help: you might have meant to compare for equality
|
|
||||||
|
|
|
||||||
LL | if None == x { }
|
|
||||||
| +
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,6 @@ mod A {
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
A::C = 1;
|
A::C = 1;
|
||||||
//~^ ERROR: invalid left-hand side of assignment
|
//~^ ERROR: mismatched types
|
||||||
//~| ERROR: struct `C` is private
|
//~| ERROR: unit struct `C` is private
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,15 +10,18 @@ note: the unit struct `C` is defined here
|
||||||
LL | struct C;
|
LL | struct C;
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error[E0070]: invalid left-hand side of assignment
|
error[E0308]: mismatched types
|
||||||
--> $DIR/issue-13407.rs:6:10
|
--> $DIR/issue-13407.rs:6:5
|
||||||
|
|
|
|
||||||
|
LL | struct C;
|
||||||
|
| -------- unit struct defined here
|
||||||
|
...
|
||||||
LL | A::C = 1;
|
LL | A::C = 1;
|
||||||
| ---- ^
|
| ^^^^ - this expression has type `{integer}`
|
||||||
| |
|
| |
|
||||||
| cannot assign to this expression
|
| expected integer, found `C`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0070, E0603.
|
Some errors have detailed explanations: E0308, E0603.
|
||||||
For more information about an error, try `rustc --explain E0070`.
|
For more information about an error, try `rustc --explain E0308`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue