base drop order on the first sub-branch
This commit is contained in:
parent
856e3816c3
commit
ea1eca5e3b
6 changed files with 49 additions and 55 deletions
|
|
@ -563,17 +563,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// we lower the guard.
|
||||
// As a result, we end up with the drop order of the last sub-branch we lower. To use
|
||||
// the drop order for the first sub-branch, we lower sub-branches in reverse (#142163).
|
||||
// TODO: I'm saving the breaking change for the next commit. For now, a stopgap:
|
||||
let sub_branch_to_use_the_drops_from =
|
||||
if arm_match_scope.is_some() { Position::Last } else { Position::First };
|
||||
let target_block = self.cfg.start_new_block();
|
||||
for (pos, sub_branch) in branch.sub_branches.into_iter().with_position() {
|
||||
for (pos, sub_branch) in branch.sub_branches.into_iter().rev().with_position() {
|
||||
debug_assert!(pos != Position::Only);
|
||||
let schedule_drops = if pos == sub_branch_to_use_the_drops_from {
|
||||
ScheduleDrops::Yes
|
||||
} else {
|
||||
ScheduleDrops::No
|
||||
};
|
||||
let schedule_drops =
|
||||
if pos == Position::Last { ScheduleDrops::Yes } else { ScheduleDrops::No };
|
||||
let binding_end = self.bind_and_guard_matched_candidate(
|
||||
sub_branch,
|
||||
fake_borrow_temps,
|
||||
|
|
|
|||
|
|
@ -85,11 +85,11 @@
|
|||
_8 = &(_2.2: std::string::String);
|
||||
- _3 = &fake shallow (_2.0: bool);
|
||||
- _4 = &fake shallow (_2.1: bool);
|
||||
StorageLive(_12);
|
||||
StorageLive(_13);
|
||||
_13 = copy _1;
|
||||
- switchInt(move _13) -> [0: bb16, otherwise: bb15];
|
||||
+ switchInt(move _13) -> [0: bb13, otherwise: bb12];
|
||||
StorageLive(_9);
|
||||
StorageLive(_10);
|
||||
_10 = copy _1;
|
||||
- switchInt(move _10) -> [0: bb12, otherwise: bb11];
|
||||
+ switchInt(move _10) -> [0: bb9, otherwise: bb8];
|
||||
}
|
||||
|
||||
- bb9: {
|
||||
|
|
@ -100,11 +100,11 @@
|
|||
_8 = &(_2.2: std::string::String);
|
||||
- _3 = &fake shallow (_2.0: bool);
|
||||
- _4 = &fake shallow (_2.1: bool);
|
||||
StorageLive(_9);
|
||||
StorageLive(_10);
|
||||
_10 = copy _1;
|
||||
- switchInt(move _10) -> [0: bb12, otherwise: bb11];
|
||||
+ switchInt(move _10) -> [0: bb9, otherwise: bb8];
|
||||
StorageLive(_12);
|
||||
StorageLive(_13);
|
||||
_13 = copy _1;
|
||||
- switchInt(move _13) -> [0: bb16, otherwise: bb15];
|
||||
+ switchInt(move _13) -> [0: bb13, otherwise: bb12];
|
||||
}
|
||||
|
||||
- bb10: {
|
||||
|
|
@ -139,7 +139,7 @@
|
|||
- FakeRead(ForGuardBinding, _6);
|
||||
- FakeRead(ForGuardBinding, _8);
|
||||
StorageLive(_5);
|
||||
_5 = copy (_2.1: bool);
|
||||
_5 = copy (_2.0: bool);
|
||||
StorageLive(_7);
|
||||
_7 = move (_2.2: std::string::String);
|
||||
- goto -> bb10;
|
||||
|
|
@ -152,8 +152,8 @@
|
|||
StorageDead(_9);
|
||||
StorageDead(_8);
|
||||
StorageDead(_6);
|
||||
- falseEdge -> [real: bb1, imaginary: bb1];
|
||||
+ goto -> bb1;
|
||||
- falseEdge -> [real: bb3, imaginary: bb3];
|
||||
+ goto -> bb2;
|
||||
}
|
||||
|
||||
- bb15: {
|
||||
|
|
@ -181,7 +181,7 @@
|
|||
- FakeRead(ForGuardBinding, _6);
|
||||
- FakeRead(ForGuardBinding, _8);
|
||||
StorageLive(_5);
|
||||
_5 = copy (_2.0: bool);
|
||||
_5 = copy (_2.1: bool);
|
||||
StorageLive(_7);
|
||||
_7 = move (_2.2: std::string::String);
|
||||
- goto -> bb10;
|
||||
|
|
@ -194,8 +194,8 @@
|
|||
StorageDead(_12);
|
||||
StorageDead(_8);
|
||||
StorageDead(_6);
|
||||
- falseEdge -> [real: bb3, imaginary: bb3];
|
||||
+ goto -> bb2;
|
||||
- falseEdge -> [real: bb1, imaginary: bb1];
|
||||
+ goto -> bb1;
|
||||
}
|
||||
|
||||
- bb19: {
|
||||
|
|
|
|||
|
|
@ -85,11 +85,11 @@
|
|||
_8 = &(_2.2: std::string::String);
|
||||
- _3 = &fake shallow (_2.0: bool);
|
||||
- _4 = &fake shallow (_2.1: bool);
|
||||
StorageLive(_12);
|
||||
StorageLive(_13);
|
||||
_13 = copy _1;
|
||||
- switchInt(move _13) -> [0: bb16, otherwise: bb15];
|
||||
+ switchInt(move _13) -> [0: bb13, otherwise: bb12];
|
||||
StorageLive(_9);
|
||||
StorageLive(_10);
|
||||
_10 = copy _1;
|
||||
- switchInt(move _10) -> [0: bb12, otherwise: bb11];
|
||||
+ switchInt(move _10) -> [0: bb9, otherwise: bb8];
|
||||
}
|
||||
|
||||
- bb9: {
|
||||
|
|
@ -100,11 +100,11 @@
|
|||
_8 = &(_2.2: std::string::String);
|
||||
- _3 = &fake shallow (_2.0: bool);
|
||||
- _4 = &fake shallow (_2.1: bool);
|
||||
StorageLive(_9);
|
||||
StorageLive(_10);
|
||||
_10 = copy _1;
|
||||
- switchInt(move _10) -> [0: bb12, otherwise: bb11];
|
||||
+ switchInt(move _10) -> [0: bb9, otherwise: bb8];
|
||||
StorageLive(_12);
|
||||
StorageLive(_13);
|
||||
_13 = copy _1;
|
||||
- switchInt(move _13) -> [0: bb16, otherwise: bb15];
|
||||
+ switchInt(move _13) -> [0: bb13, otherwise: bb12];
|
||||
}
|
||||
|
||||
- bb10: {
|
||||
|
|
@ -139,7 +139,7 @@
|
|||
- FakeRead(ForGuardBinding, _6);
|
||||
- FakeRead(ForGuardBinding, _8);
|
||||
StorageLive(_5);
|
||||
_5 = copy (_2.1: bool);
|
||||
_5 = copy (_2.0: bool);
|
||||
StorageLive(_7);
|
||||
_7 = move (_2.2: std::string::String);
|
||||
- goto -> bb10;
|
||||
|
|
@ -152,8 +152,8 @@
|
|||
StorageDead(_9);
|
||||
StorageDead(_8);
|
||||
StorageDead(_6);
|
||||
- falseEdge -> [real: bb1, imaginary: bb1];
|
||||
+ goto -> bb1;
|
||||
- falseEdge -> [real: bb3, imaginary: bb3];
|
||||
+ goto -> bb2;
|
||||
}
|
||||
|
||||
- bb15: {
|
||||
|
|
@ -181,7 +181,7 @@
|
|||
- FakeRead(ForGuardBinding, _6);
|
||||
- FakeRead(ForGuardBinding, _8);
|
||||
StorageLive(_5);
|
||||
_5 = copy (_2.0: bool);
|
||||
_5 = copy (_2.1: bool);
|
||||
StorageLive(_7);
|
||||
_7 = move (_2.2: std::string::String);
|
||||
- goto -> bb10;
|
||||
|
|
@ -194,8 +194,8 @@
|
|||
StorageDead(_12);
|
||||
StorageDead(_8);
|
||||
StorageDead(_6);
|
||||
- falseEdge -> [real: bb3, imaginary: bb3];
|
||||
+ goto -> bb2;
|
||||
- falseEdge -> [real: bb1, imaginary: bb1];
|
||||
+ goto -> bb1;
|
||||
}
|
||||
|
||||
- bb19: {
|
||||
|
|
|
|||
|
|
@ -65,12 +65,12 @@ fn main() {
|
|||
match (LogDrop(o, 3), Ok(LogDrop(o, 1)), LogDrop(o, 2)) { (x, Ok(y) | Err(y), z) => {} }
|
||||
});
|
||||
assert_drop_order(1..=2, |o| {
|
||||
// The last or-pattern alternative determines the bindings' drop order: `x`, `y`.
|
||||
match (true, LogDrop(o, 1), LogDrop(o, 2)) { (true, x, y) | (false, y, x) => {} }
|
||||
// The first or-pattern alternative determines the bindings' drop order: `y`, `x`.
|
||||
match (true, LogDrop(o, 2), LogDrop(o, 1)) { (true, x, y) | (false, y, x) => {} }
|
||||
});
|
||||
assert_drop_order(1..=2, |o| {
|
||||
// That drop order is used regardless of which or-pattern alternative matches: `x`, `y`.
|
||||
match (false, LogDrop(o, 2), LogDrop(o, 1)) { (true, x, y) | (false, y, x) => {} }
|
||||
// That drop order is used regardless of which or-pattern alternative matches: `y`, `x`.
|
||||
match (false, LogDrop(o, 1), LogDrop(o, 2)) { (true, x, y) | (false, y, x) => {} }
|
||||
});
|
||||
|
||||
// Function params are visited one-by-one, and the order of bindings within a param's pattern is
|
||||
|
|
|
|||
|
|
@ -17,15 +17,15 @@ fn main() {
|
|||
(mut long2, ref short2) if true => long2.0 = &short2,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
// This depends on the binding modes of the final or-pattern alternatives (see #142163):
|
||||
// This depends on the binding modes of the first or-pattern alternatives:
|
||||
let res: &Result<u8, &u8> = &Ok(1);
|
||||
match (Struct(&&0), res) {
|
||||
(mut long3, Ok(short3) | &Err(short3)) if true => long3.0 = &short3,
|
||||
//~^ ERROR `short3` does not live long enough
|
||||
_ => unreachable!(),
|
||||
}
|
||||
match (Struct(&&0), res) {
|
||||
(mut long4, &Err(short4) | Ok(short4)) if true => long4.0 = &short4,
|
||||
//~^ ERROR `short4` does not live long enough
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,15 +11,15 @@ LL | (mut long1, ref short1) => long1.0 = &short1,
|
|||
|
|
||||
= note: values in a scope are dropped in the opposite order they are defined
|
||||
|
||||
error[E0597]: `short3` does not live long enough
|
||||
--> $DIR/eager-by-ref-binding-for-guards.rs:23:69
|
||||
error[E0597]: `short4` does not live long enough
|
||||
--> $DIR/eager-by-ref-binding-for-guards.rs:27:69
|
||||
|
|
||||
LL | (mut long3, Ok(short3) | &Err(short3)) if true => long3.0 = &short3,
|
||||
| ------ ^^^^^^-
|
||||
| | | |
|
||||
| | | `short3` dropped here while still borrowed
|
||||
| | | borrow might be used here, when `long3` is dropped and runs the `Drop` code for type `Struct`
|
||||
| binding `short3` declared here borrowed value does not live long enough
|
||||
LL | (mut long4, &Err(short4) | Ok(short4)) if true => long4.0 = &short4,
|
||||
| ------ ^^^^^^-
|
||||
| | | |
|
||||
| | | `short4` dropped here while still borrowed
|
||||
| | | borrow might be used here, when `long4` is dropped and runs the `Drop` code for type `Struct`
|
||||
| binding `short4` declared here borrowed value does not live long enough
|
||||
|
|
||||
= note: values in a scope are dropped in the opposite order they are defined
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue