Skip to content

Commit a8c784c

Browse files
varkorfanzier
authored andcommitted
Add destructuring_assignment feature gate
1 parent 601c13c commit a8c784c

File tree

9 files changed

+97
-86
lines changed

9 files changed

+97
-86
lines changed

compiler/rustc_feature/src/active.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,9 @@ declare_features! (
610610
/// Allows unsized fn parameters.
611611
(active, unsized_fn_params, "1.49.0", Some(48055), None),
612612

613+
/// Allows the use of destructuring assignments.
614+
(active, destructuring_assignment, "1.49.0", None, None),
615+
613616
// -------------------------------------------------------------------------
614617
// feature-group-end: actual feature gates
615618
// -------------------------------------------------------------------------

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ symbols! {
434434
deref_mut,
435435
deref_target,
436436
derive,
437+
destructuring_assignment,
437438
diagnostic,
438439
direct,
439440
discriminant_kind,

compiler/rustc_typeck/src/check/expr.rs

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
3939
use rustc_middle::ty::Ty;
4040
use rustc_middle::ty::TypeFoldable;
4141
use rustc_middle::ty::{AdtKind, Visibility};
42+
use rustc_session::parse::feature_err;
4243
use rustc_span::hygiene::DesugaringKind;
4344
use rustc_span::source_map::Span;
4445
use rustc_span::symbol::{kw, sym, Ident, Symbol};
@@ -737,19 +738,37 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
737738
err_code: &'static str,
738739
expr_span: &Span,
739740
) {
740-
if !lhs.is_syntactic_place_expr() {
741-
// FIXME: Make this use SessionDiagnostic once error codes can be dynamically set.
742-
let mut err = self.tcx.sess.struct_span_err_with_code(
743-
*expr_span,
744-
"invalid left-hand side of assignment",
745-
DiagnosticId::Error(err_code.into()),
746-
);
747-
err.span_label(lhs.span, "cannot assign to this expression");
748-
if self.is_destructuring_place_expr(lhs) {
749-
err.note("destructuring assignments are not currently supported");
750-
err.note("for more information, see https://github.com/rust-lang/rfcs/issues/372");
741+
if lhs.is_syntactic_place_expr() {
742+
return;
743+
}
744+
745+
let da = self.is_destructuring_place_expr(lhs);
746+
match (da, self.tcx.features().destructuring_assignment) {
747+
// Valid destructuring assignment.
748+
(true, true) => {}
749+
750+
// Destructuring assignment, but the feature is not enabled.
751+
(true, false) => {
752+
feature_err(
753+
&self.tcx.sess.parse_sess,
754+
sym::destructuring_assignment,
755+
*expr_span,
756+
"destructuring assignments are unstable",
757+
)
758+
.emit();
759+
}
760+
761+
// Invalid assignment.
762+
(false, _) => {
763+
// FIXME: Make this use SessionDiagnostic once error codes can be dynamically set.
764+
let mut err = self.tcx.sess.struct_span_err_with_code(
765+
*expr_span,
766+
"invalid left-hand side of assignment",
767+
DiagnosticId::Error(err_code.into()),
768+
);
769+
err.span_label(lhs.span, "cannot assign to this expression");
770+
err.emit();
751771
}
752-
err.emit();
753772
}
754773
}
755774

src/test/ui/bad/bad-expr-lhs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ fn main() {
44
(1, 2) = (3, 4); //~ ERROR invalid left-hand side of assignment
55

66
let (a, b) = (1, 2);
7-
(a, b) = (3, 4); //~ ERROR invalid left-hand side of assignment
7+
(a, b) = (3, 4); //~ ERROR destructuring assignments are unstable
88

99
None = Some(3); //~ ERROR invalid left-hand side of assignment
1010
}

src/test/ui/bad/bad-expr-lhs.stderr

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,13 @@ LL | (1, 2) = (3, 4);
2222
| |
2323
| cannot assign to this expression
2424

25-
error[E0070]: invalid left-hand side of assignment
25+
error[E0658]: destructuring assignments are unstable
2626
--> $DIR/bad-expr-lhs.rs:7:12
2727
|
2828
LL | (a, b) = (3, 4);
29-
| ------ ^
30-
| |
31-
| cannot assign to this expression
29+
| ^
3230
|
33-
= note: destructuring assignments are not currently supported
34-
= note: for more information, see https://github.com/rust-lang/rfcs/issues/372
31+
= help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
3532

3633
error[E0070]: invalid left-hand side of assignment
3734
--> $DIR/bad-expr-lhs.rs:9:10
@@ -43,5 +40,5 @@ LL | None = Some(3);
4340

4441
error: aborting due to 5 previous errors
4542

46-
Some errors have detailed explanations: E0067, E0070.
43+
Some errors have detailed explanations: E0067, E0070, E0658.
4744
For more information about an error, try `rustc --explain E0067`.

src/test/ui/destructuring-assignment/note-unsupported.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,23 @@ struct S { x: u8, y: u8 }
33
fn main() {
44
let (a, b) = (1, 2);
55

6-
(a, b) = (3, 4); //~ ERROR invalid left-hand side of assignment
7-
(a, b) += (3, 4); //~ ERROR invalid left-hand side of assignment
6+
(a, b) = (3, 4); //~ ERROR destructuring assignments are unstable
7+
(a, b) += (3, 4); //~ ERROR destructuring assignments are unstable
88
//~^ ERROR binary assignment operation `+=` cannot be applied
99

10-
[a, b] = [3, 4]; //~ ERROR invalid left-hand side of assignment
11-
[a, b] += [3, 4]; //~ ERROR invalid left-hand side of assignment
10+
[a, b] = [3, 4]; //~ ERROR destructuring assignments are unstable
11+
[a, b] += [3, 4]; //~ ERROR destructuring assignments are unstable
1212
//~^ ERROR binary assignment operation `+=` cannot be applied
1313

1414
let s = S { x: 3, y: 4 };
1515

16-
S { x: a, y: b } = s; //~ ERROR invalid left-hand side of assignment
17-
S { x: a, y: b } += s; //~ ERROR invalid left-hand side of assignment
16+
S { x: a, y: b } = s; //~ ERROR destructuring assignments are unstable
17+
S { x: a, y: b } += s; //~ ERROR destructuring assignments are unstable
1818
//~^ ERROR binary assignment operation `+=` cannot be applied
1919

20-
S { x: a, ..s } = S { x: 3, y: 4 }; //~ ERROR invalid left-hand side of assignment
20+
S { x: a, ..s } = S { x: 3, y: 4 }; //~ ERROR destructuring assignments are unstable
2121

2222
let c = 3;
2323

24-
((a, b), c) = ((3, 4), 5); //~ ERROR invalid left-hand side of assignment
24+
((a, b), c) = ((3, 4), 5); //~ ERROR destructuring assignments are unstable
2525
}
Lines changed: 34 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
error[E0070]: invalid left-hand side of assignment
2-
--> $DIR/note-unsupported.rs:6:12
1+
error[E0658]: destructuring assignments are unstable
2+
--> $DIR/destructuring-assignment.rs:6:12
33
|
44
LL | (a, b) = (3, 4);
5-
| ------ ^
6-
| |
7-
| cannot assign to this expression
5+
| ^
86
|
9-
= note: destructuring assignments are not currently supported
10-
= note: for more information, see https://github.com/rust-lang/rfcs/issues/372
7+
= help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
118

129
error[E0368]: binary assignment operation `+=` cannot be applied to type `({integer}, {integer})`
1310
--> $DIR/note-unsupported.rs:7:5
@@ -17,27 +14,21 @@ LL | (a, b) += (3, 4);
1714
| |
1815
| cannot use `+=` on type `({integer}, {integer})`
1916

20-
error[E0067]: invalid left-hand side of assignment
21-
--> $DIR/note-unsupported.rs:7:12
17+
error[E0658]: destructuring assignments are unstable
18+
--> $DIR/destructuring-assignment.rs:7:12
2219
|
2320
LL | (a, b) += (3, 4);
24-
| ------ ^^
25-
| |
26-
| cannot assign to this expression
21+
| ^^
2722
|
28-
= note: destructuring assignments are not currently supported
29-
= note: for more information, see https://github.com/rust-lang/rfcs/issues/372
23+
= help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
3024

31-
error[E0070]: invalid left-hand side of assignment
32-
--> $DIR/note-unsupported.rs:10:12
25+
error[E0658]: destructuring assignments are unstable
26+
--> $DIR/destructuring-assignment.rs:10:12
3327
|
3428
LL | [a, b] = [3, 4];
35-
| ------ ^
36-
| |
37-
| cannot assign to this expression
29+
| ^
3830
|
39-
= note: destructuring assignments are not currently supported
40-
= note: for more information, see https://github.com/rust-lang/rfcs/issues/372
31+
= help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
4132

4233
error[E0368]: binary assignment operation `+=` cannot be applied to type `[{integer}; 2]`
4334
--> $DIR/note-unsupported.rs:11:5
@@ -47,27 +38,21 @@ LL | [a, b] += [3, 4];
4738
| |
4839
| cannot use `+=` on type `[{integer}; 2]`
4940

50-
error[E0067]: invalid left-hand side of assignment
51-
--> $DIR/note-unsupported.rs:11:12
41+
error[E0658]: destructuring assignments are unstable
42+
--> $DIR/destructuring-assignment.rs:11:12
5243
|
5344
LL | [a, b] += [3, 4];
54-
| ------ ^^
55-
| |
56-
| cannot assign to this expression
45+
| ^^
5746
|
58-
= note: destructuring assignments are not currently supported
59-
= note: for more information, see https://github.com/rust-lang/rfcs/issues/372
47+
= help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
6048

61-
error[E0070]: invalid left-hand side of assignment
62-
--> $DIR/note-unsupported.rs:16:22
49+
error[E0658]: destructuring assignments are unstable
50+
--> $DIR/destructuring-assignment.rs:16:22
6351
|
6452
LL | S { x: a, y: b } = s;
65-
| ---------------- ^
66-
| |
67-
| cannot assign to this expression
53+
| ^
6854
|
69-
= note: destructuring assignments are not currently supported
70-
= note: for more information, see https://github.com/rust-lang/rfcs/issues/372
55+
= help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
7156

7257
error[E0368]: binary assignment operation `+=` cannot be applied to type `S`
7358
--> $DIR/note-unsupported.rs:17:5
@@ -79,40 +64,31 @@ LL | S { x: a, y: b } += s;
7964
|
8065
= note: an implementation of `std::ops::AddAssign` might be missing for `S`
8166

82-
error[E0067]: invalid left-hand side of assignment
83-
--> $DIR/note-unsupported.rs:17:22
67+
error[E0658]: destructuring assignments are unstable
68+
--> $DIR/destructuring-assignment.rs:17:22
8469
|
8570
LL | S { x: a, y: b } += s;
86-
| ---------------- ^^
87-
| |
88-
| cannot assign to this expression
71+
| ^^
8972
|
90-
= note: destructuring assignments are not currently supported
91-
= note: for more information, see https://github.com/rust-lang/rfcs/issues/372
73+
= help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
9274

93-
error[E0070]: invalid left-hand side of assignment
94-
--> $DIR/note-unsupported.rs:20:21
75+
error[E0658]: destructuring assignments are unstable
76+
--> $DIR/destructuring-assignment.rs:20:21
9577
|
9678
LL | S { x: a, ..s } = S { x: 3, y: 4 };
97-
| --------------- ^
98-
| |
99-
| cannot assign to this expression
79+
| ^
10080
|
101-
= note: destructuring assignments are not currently supported
102-
= note: for more information, see https://github.com/rust-lang/rfcs/issues/372
81+
= help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
10382

104-
error[E0070]: invalid left-hand side of assignment
105-
--> $DIR/note-unsupported.rs:24:17
83+
error[E0658]: destructuring assignments are unstable
84+
--> $DIR/destructuring-assignment.rs:24:17
10685
|
10786
LL | ((a, b), c) = ((3, 4), 5);
108-
| ----------- ^
109-
| |
110-
| cannot assign to this expression
87+
| ^
11188
|
112-
= note: destructuring assignments are not currently supported
113-
= note: for more information, see https://github.com/rust-lang/rfcs/issues/372
89+
= help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
11490

11591
error: aborting due to 11 previous errors
11692

117-
Some errors have detailed explanations: E0067, E0070, E0368.
118-
For more information about an error, try `rustc --explain E0067`.
93+
Some errors have detailed explanations: E0368, E0658.
94+
For more information about an error, try `rustc --explain E0368`.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fn main() {
2+
let (a, b) = (0, 1);
3+
(a, b) = (2, 3); //~ ERROR destructuring assignments are unstable
4+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0658]: destructuring assignments are unstable
2+
--> $DIR/feature-gate-destructuring_assignment.rs:3:12
3+
|
4+
LL | (a, b) = (2, 3);
5+
| ^
6+
|
7+
= help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0658`.

0 commit comments

Comments
 (0)