mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-28 09:44:08 +00:00
Rollup merge of #78836 - fanzier:struct-and-slice-destructuring, r=petrochenkov
Implement destructuring assignment for structs and slices This is the second step towards implementing destructuring assignment (RFC: rust-lang/rfcs#2909, tracking issue: #71126). This PR is the second part of #71156, which was split up to allow for easier review. Note that the first PR (#78748) is not merged yet, so it is included as the first commit in this one. I thought this would allow the review to start earlier because I have some time this weekend to respond to reviews. If ``@petrochenkov`` prefers to wait until the first PR is merged, I totally understand, of course. This PR implements destructuring assignment for (tuple) structs and slices. In order to do this, the following *parser change* was necessary: struct expressions are not required to have a base expression, i.e. `Struct { a: 1, .. }` becomes legal (in order to act like a struct pattern). Unfortunately, this PR slightly regresses the diagnostics implemented in #77283. However, it is only a missing help message in `src/test/ui/issues/issue-77218.rs`. Other instances of this diagnostic are not affected. Since I don't exactly understand how this help message works and how to fix it yet, I was hoping it's OK to regress this temporarily and fix it in a follow-up PR. Thanks to ``@varkor`` who helped with the implementation, particularly around the struct rest changes. r? ``@petrochenkov``
This commit is contained in:
commit
3a648ffc02
@ -107,6 +107,15 @@ pub fn eq_expr_opt(l: &Option<P<Expr>>, r: &Option<P<Expr>>) -> bool {
|
|||||||
both(l, r, |l, r| eq_expr(l, r))
|
both(l, r, |l, r| eq_expr(l, r))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn eq_struct_rest(l: &StructRest, r: &StructRest) -> bool {
|
||||||
|
match (l, r) {
|
||||||
|
(StructRest::Base(lb), StructRest::Base(rb)) => eq_expr(lb, rb),
|
||||||
|
(StructRest::Rest(_), StructRest::Rest(_)) => true,
|
||||||
|
(StructRest::None, StructRest::None) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
|
pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
|
||||||
use ExprKind::*;
|
use ExprKind::*;
|
||||||
if !over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r)) {
|
if !over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r)) {
|
||||||
@ -150,7 +159,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
|
|||||||
(Path(lq, lp), Path(rq, rp)) => both(lq, rq, |l, r| eq_qself(l, r)) && eq_path(lp, rp),
|
(Path(lq, lp), Path(rq, rp)) => both(lq, rq, |l, r| eq_qself(l, r)) && eq_path(lp, rp),
|
||||||
(MacCall(l), MacCall(r)) => eq_mac_call(l, r),
|
(MacCall(l), MacCall(r)) => eq_mac_call(l, r),
|
||||||
(Struct(lp, lfs, lb), Struct(rp, rfs, rb)) => {
|
(Struct(lp, lfs, lb), Struct(rp, rfs, rb)) => {
|
||||||
eq_path(lp, rp) && eq_expr_opt(lb, rb) && unordered_over(lfs, rfs, |l, r| eq_field(l, r))
|
eq_path(lp, rp) && eq_struct_rest(lb, rb) && unordered_over(lfs, rfs, |l, r| eq_field(l, r))
|
||||||
},
|
},
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,14 @@
|
|||||||
|
error[E0658]: destructuring assignments are unstable
|
||||||
|
--> $DIR/ice-6250.rs:12:25
|
||||||
|
|
|
||||||
|
LL | Some(reference) = cache.data.get(key) {
|
||||||
|
| --------------- ^
|
||||||
|
| |
|
||||||
|
| cannot assign to this expression
|
||||||
|
|
|
||||||
|
= note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
|
||||||
|
= help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0601]: `main` function not found in crate `ice_6250`
|
error[E0601]: `main` function not found in crate `ice_6250`
|
||||||
--> $DIR/ice-6250.rs:4:1
|
--> $DIR/ice-6250.rs:4:1
|
||||||
|
|
|
|
||||||
@ -10,18 +21,22 @@ LL | | }
|
|||||||
LL | | }
|
LL | | }
|
||||||
| |_^ consider adding a `main` function to `$DIR/ice-6250.rs`
|
| |_^ consider adding a `main` function to `$DIR/ice-6250.rs`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/ice-6250.rs:12:14
|
||||||
|
|
|
||||||
|
LL | Some(reference) = cache.data.get(key) {
|
||||||
|
| ^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| expected integer, found `&i32`
|
||||||
|
| help: consider dereferencing the borrow: `*reference`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/ice-6250.rs:12:9
|
--> $DIR/ice-6250.rs:12:9
|
||||||
|
|
|
|
||||||
LL | Some(reference) = cache.data.get(key) {
|
LL | Some(reference) = cache.data.get(key) {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()`
|
||||||
|
|
|
||||||
help: you might have meant to use pattern matching
|
|
||||||
|
|
|
||||||
LL | let Some(reference) = cache.data.get(key) {
|
|
||||||
| ^^^
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0308, E0601.
|
Some errors have detailed explanations: E0308, E0601, E0658.
|
||||||
For more information about an error, try `rustc --explain E0308`.
|
For more information about an error, try `rustc --explain E0308`.
|
||||||
|
Loading…
Reference in New Issue
Block a user