Skip to content

Commit c740839

Browse files
committed
Recognise nested tuples/arrays/structs
1 parent a2a0bb2 commit c740839

File tree

3 files changed

+30
-12
lines changed

3 files changed

+30
-12
lines changed

src/librustc_typeck/check/expr.rs

+14-11
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
761761
);
762762
}
763763

764+
fn is_destructuring_place_expr(&self, expr: &'tcx hir::Expr) -> bool {
765+
match &expr.kind {
766+
ExprKind::Array(comps) | ExprKind::Tup(comps) => {
767+
comps.iter().all(|e| self.is_destructuring_place_expr(e))
768+
}
769+
ExprKind::Struct(_path, fields, rest) => {
770+
rest.as_ref().map(|e| self.is_destructuring_place_expr(e)).unwrap_or(true) &&
771+
fields.iter().all(|f| self.is_destructuring_place_expr(&f.expr))
772+
}
773+
_ => expr.is_syntactic_place_expr(),
774+
}
775+
}
776+
764777
pub(crate) fn check_lhs_assignable(
765778
&self,
766779
lhs: &'tcx hir::Expr,
@@ -774,17 +787,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
774787
DiagnosticId::Error(err_code.into()),
775788
);
776789
err.span_label(lhs.span, "cannot assign to this expression");
777-
let destructuring_assignment = match &lhs.kind {
778-
ExprKind::Array(comps) | ExprKind::Tup(comps) => {
779-
comps.iter().all(|e| e.is_syntactic_place_expr())
780-
}
781-
ExprKind::Struct(_path, fields, rest) => {
782-
rest.as_ref().map(|e| e.is_syntactic_place_expr()).unwrap_or(true) &&
783-
fields.iter().all(|f| f.expr.is_syntactic_place_expr())
784-
}
785-
_ => false,
786-
};
787-
if destructuring_assignment {
790+
if self.is_destructuring_place_expr(lhs) {
788791
err.note("destructuring assignments are not yet supported");
789792
err.note(
790793
"for more information, see https://github.com/rust-lang/rfcs/issues/372",

src/test/ui/bad/destructuring-assignment.rs

+4
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,8 @@ fn main() {
1818
//~^ ERROR binary assignment operation `+=` cannot be applied
1919

2020
S { x: a, ..s } = S { x: 3, y: 4 }; //~ ERROR invalid left-hand side of assignment
21+
22+
let c = 3;
23+
24+
((a, b), c) = ((3, 4), 5); //~ ERROR invalid left-hand side of assignment
2125
}

src/test/ui/bad/destructuring-assignment.stderr

+12-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,18 @@ LL | S { x: a, ..s } = S { x: 3, y: 4 };
105105
= note: destructuring assignments are not yet supported
106106
= note: for more information, see https://github.com/rust-lang/rfcs/issues/372
107107

108-
error: aborting due to 10 previous errors
108+
error[E0070]: invalid left-hand side of assignment
109+
--> $DIR/destructuring-assignment.rs:24:5
110+
|
111+
LL | ((a, b), c) = ((3, 4), 5);
112+
| -----------^^^^^^^^^^^^^^
113+
| |
114+
| cannot assign to this expression
115+
|
116+
= note: destructuring assignments are not yet supported
117+
= note: for more information, see https://github.com/rust-lang/rfcs/issues/372
118+
119+
error: aborting due to 11 previous errors
109120

110121
Some errors have detailed explanations: E0067, E0070, E0368.
111122
For more information about an error, try `rustc --explain E0067`.

0 commit comments

Comments
 (0)