base drop order on the first sub-branch

This commit is contained in:
dianne 2025-07-09 02:49:31 -07:00
parent 856e3816c3
commit ea1eca5e3b
6 changed files with 49 additions and 55 deletions

View file

@ -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,

View file

@ -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: {

View file

@ -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: {

View file

@ -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

View file

@ -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!(),
}
}

View file

@ -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