about summary refs log tree commit diff
diff options
context:
space:
mode:
authordianne <diannes.gm@gmail.com>2025-07-09 02:49:31 -0700
committerdianne <diannes.gm@gmail.com>2025-08-06 12:13:12 -0700
commitea1eca5e3b6e5300696d06c56190f8d617104edf (patch)
tree3bd95d805a1c8c0e384d19c8eb09b0b58d4bb94f
parent856e3816c38351ce2e34ec69d7719c2ea3d66e4c (diff)
downloadrust-ea1eca5e3b6e5300696d06c56190f8d617104edf.tar.gz
rust-ea1eca5e3b6e5300696d06c56190f8d617104edf.zip
base drop order on the first sub-branch
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/mod.rs12
-rw-r--r--tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff32
-rw-r--r--tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff32
-rw-r--r--tests/ui/drop/or-pattern-drop-order.rs8
-rw-r--r--tests/ui/dropck/eager-by-ref-binding-for-guards.rs4
-rw-r--r--tests/ui/dropck/eager-by-ref-binding-for-guards.stderr16
6 files changed, 49 insertions, 55 deletions
diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs
index 9abb44143df..29c5670b0bf 100644
--- a/compiler/rustc_mir_build/src/builder/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs
@@ -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,
diff --git a/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff
index b3eb3e1f8b9..484bc7dad12 100644
--- a/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff
+++ b/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff
@@ -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: {
diff --git a/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff
index b3eb3e1f8b9..484bc7dad12 100644
--- a/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff
+++ b/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff
@@ -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: {
diff --git a/tests/ui/drop/or-pattern-drop-order.rs b/tests/ui/drop/or-pattern-drop-order.rs
index fdc28225c35..a4e4d24995b 100644
--- a/tests/ui/drop/or-pattern-drop-order.rs
+++ b/tests/ui/drop/or-pattern-drop-order.rs
@@ -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
diff --git a/tests/ui/dropck/eager-by-ref-binding-for-guards.rs b/tests/ui/dropck/eager-by-ref-binding-for-guards.rs
index 3f475839171..90ff9a747ae 100644
--- a/tests/ui/dropck/eager-by-ref-binding-for-guards.rs
+++ b/tests/ui/dropck/eager-by-ref-binding-for-guards.rs
@@ -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!(),
     }
 }
diff --git a/tests/ui/dropck/eager-by-ref-binding-for-guards.stderr b/tests/ui/dropck/eager-by-ref-binding-for-guards.stderr
index cb1a04cd444..2648ce6f99c 100644
--- a/tests/ui/dropck/eager-by-ref-binding-for-guards.stderr
+++ b/tests/ui/dropck/eager-by-ref-binding-for-guards.stderr
@@ -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