Skip to content

reverse binding order in matches to allow the subbinding of copyable fields in bindings after @ #78638

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Nov 5, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
review comments
  • Loading branch information
vn-ki committed Nov 3, 2020
commit 5827fbadf6feaa3da42d7223ac9f10148c827a89
20 changes: 10 additions & 10 deletions compiler/rustc_mir_build/src/build/matches/simplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
candidate: &mut Candidate<'pat, 'tcx>,
) -> bool {
// repeatedly simplify match pairs until fixed point is reached
debug!("simplify_candidate(candidate={:?})", candidate);
debug!(?candidate, "simplify_candidate");

// exisiting_bindings and new_bindings exists to keep the semantics in order
// reversing the binding order for bindings after `@` change binding order in places
// existing_bindings and new_bindings exists to keep the semantics in order.
// Reversing the binding order for bindings after `@` changes the binding order in places
// it shouldn't be changed, for example `let (Some(a), Some(b)) = (x, y)`
//
// To avoid this, the binding occurs in the following manner:
Expand All @@ -64,16 +64,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// binding in iter 2: [6, 7]
//
// final binding: [1, 2, 3, 6, 7, 4, 5]
let mut exisiting_bindings = mem::take(&mut candidate.bindings);
let mut existing_bindings = mem::take(&mut candidate.bindings);
let mut new_bindings = Vec::new();
loop {
let match_pairs = mem::take(&mut candidate.match_pairs);

if let [MatchPair { pattern: Pat { kind: box PatKind::Or { pats }, .. }, place }] =
*match_pairs
{
exisiting_bindings.extend_from_slice(&new_bindings);
mem::swap(&mut candidate.bindings, &mut exisiting_bindings);
existing_bindings.extend_from_slice(&new_bindings);
mem::swap(&mut candidate.bindings, &mut existing_bindings);
candidate.subcandidates = self.create_or_subcandidates(candidate, place, pats);
return true;
}
Expand All @@ -89,7 +89,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}
}
// issue #69971: the binding order should be right to left if there are more
// Avoid issue #69971: the binding order should be right to left if there are more
// bindings after `@` to please the borrow checker
// Ex
// struct NonCopyStruct {
Expand All @@ -107,15 +107,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
candidate.bindings.clear();

if !changed {
exisiting_bindings.extend_from_slice(&new_bindings);
mem::swap(&mut candidate.bindings, &mut exisiting_bindings);
existing_bindings.extend_from_slice(&new_bindings);
mem::swap(&mut candidate.bindings, &mut existing_bindings);
// Move or-patterns to the end, because they can result in us
// creating additional candidates, so we want to test them as
// late as possible.
candidate
.match_pairs
.sort_by_key(|pair| matches!(*pair.pattern.kind, PatKind::Or { .. }));
debug!("simplify_candidate: simplifed {:?}", candidate);
debug!(simplified = ?candidate, "simplify_candidate");
return false; // if we were not able to simplify any, done.
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ struct C;
struct NC<A, B>(A, B);

fn main() {
// this compiles
let a @ NC(b, c) = NC(C, C);

let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C));
//~^ ERROR use of partially moved value
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0382]: use of partially moved value
--> $DIR/copy-and-move-mixed.rs:11:9
--> $DIR/copy-and-move-mixed.rs:14:9
|
LL | let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C));
| ^^^^^^^^^^------------^
Expand Down