summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-12-18 21:57:20 +0000
committerJosh Stone <jistone@redhat.com>2025-01-02 14:28:32 -0800
commit432bd9de3259e5cd73b0e798a05ddffe8eea7759 (patch)
treee7c2ff4cdc520f0de99f94e611bb53781e696629
parent3113133cb7321abd41c9af2a74af1d75f75d60ab (diff)
downloadrust-432bd9de3259e5cd73b0e798a05ddffe8eea7759.tar.gz
rust-432bd9de3259e5cd73b0e798a05ddffe8eea7759.zip
Separate DropKind::ForLint
(cherry picked from commit 5e079011eafbb1d5fc779c14c7a29d4a620574f9)
-rw-r--r--compiler/rustc_mir_build/src/build/scope.rs108
-rw-r--r--tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-abort.mir74
-rw-r--r--tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-unwind.mir74
-rw-r--r--tests/mir-opt/tail_expr_drop_order_unwind.rs4
4 files changed, 121 insertions, 139 deletions
diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs
index 636e47b7ad2..4530df00c72 100644
--- a/compiler/rustc_mir_build/src/build/scope.rs
+++ b/compiler/rustc_mir_build/src/build/scope.rs
@@ -151,15 +151,13 @@ struct DropData {
 
     /// Whether this is a value Drop or a StorageDead.
     kind: DropKind,
-
-    /// Whether this is a backwards-incompatible drop lint
-    backwards_incompatible_lint: bool,
 }
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub(crate) enum DropKind {
     Value,
     Storage,
+    ForLint,
 }
 
 #[derive(Debug)]
@@ -248,7 +246,7 @@ impl Scope {
     /// use of optimizations in the MIR coroutine transform.
     fn needs_cleanup(&self) -> bool {
         self.drops.iter().any(|drop| match drop.kind {
-            DropKind::Value => true,
+            DropKind::Value | DropKind::ForLint => true,
             DropKind::Storage => false,
         })
     }
@@ -277,12 +275,8 @@ impl DropTree {
         // represents the block in the tree that should be jumped to once all
         // of the required drops have been performed.
         let fake_source_info = SourceInfo::outermost(DUMMY_SP);
-        let fake_data = DropData {
-            source_info: fake_source_info,
-            local: Local::MAX,
-            kind: DropKind::Storage,
-            backwards_incompatible_lint: false,
-        };
+        let fake_data =
+            DropData { source_info: fake_source_info, local: Local::MAX, kind: DropKind::Storage };
         let drops = IndexVec::from_raw(vec![DropNode { data: fake_data, next: DropIdx::MAX }]);
         Self { drops, entry_points: Vec::new(), existing_drops_map: FxHashMap::default() }
     }
@@ -411,6 +405,27 @@ impl DropTree {
                     };
                     cfg.terminate(block, drop_node.data.source_info, terminator);
                 }
+                DropKind::ForLint => {
+                    let stmt = Statement {
+                        source_info: drop_node.data.source_info,
+                        kind: StatementKind::BackwardIncompatibleDropHint {
+                            place: Box::new(drop_node.data.local.into()),
+                            reason: BackwardIncompatibleDropReason::Edition2024,
+                        },
+                    };
+                    cfg.push(block, stmt);
+                    let target = blocks[drop_node.next].unwrap();
+                    if target != block {
+                        // Diagnostics don't use this `Span` but debuginfo
+                        // might. Since we don't want breakpoints to be placed
+                        // here, especially when this is on an unwind path, we
+                        // use `DUMMY_SP`.
+                        let source_info =
+                            SourceInfo { span: DUMMY_SP, ..drop_node.data.source_info };
+                        let terminator = TerminatorKind::Goto { target };
+                        cfg.terminate(block, source_info, terminator);
+                    }
+                }
                 // Root nodes don't correspond to a drop.
                 DropKind::Storage if drop_idx == ROOT_NODE => {}
                 DropKind::Storage => {
@@ -770,12 +785,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     let local =
                         place.as_local().unwrap_or_else(|| bug!("projection in tail call args"));
 
-                    Some(DropData {
-                        source_info,
-                        local,
-                        kind: DropKind::Value,
-                        backwards_incompatible_lint: false,
-                    })
+                    Some(DropData { source_info, local, kind: DropKind::Value })
                 }
                 Operand::Constant(_) => None,
             })
@@ -822,6 +832,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         });
                         block = next;
                     }
+                    DropKind::ForLint => {
+                        self.cfg.push(block, Statement {
+                            source_info,
+                            kind: StatementKind::BackwardIncompatibleDropHint {
+                                place: Box::new(local.into()),
+                                reason: BackwardIncompatibleDropReason::Edition2024,
+                            },
+                        });
+                    }
                     DropKind::Storage => {
                         // Only temps and vars need their storage dead.
                         assert!(local.index() > self.arg_count);
@@ -1021,7 +1040,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         drop_kind: DropKind,
     ) {
         let needs_drop = match drop_kind {
-            DropKind::Value => {
+            DropKind::Value | DropKind::ForLint => {
                 if !self.local_decls[local].ty.needs_drop(self.tcx, self.typing_env()) {
                     return;
                 }
@@ -1101,7 +1120,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     source_info: SourceInfo { span: scope_end, scope: scope.source_scope },
                     local,
                     kind: drop_kind,
-                    backwards_incompatible_lint: false,
                 });
 
                 return;
@@ -1135,8 +1153,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 scope.drops.push(DropData {
                     source_info: SourceInfo { span: scope_end, scope: scope.source_scope },
                     local,
-                    kind: DropKind::Value,
-                    backwards_incompatible_lint: true,
+                    kind: DropKind::ForLint,
                 });
 
                 return;
@@ -1430,25 +1447,38 @@ fn build_scope_drops<'tcx>(
                     continue;
                 }
 
-                if drop_data.backwards_incompatible_lint {
-                    cfg.push(block, Statement {
-                        source_info,
-                        kind: StatementKind::BackwardIncompatibleDropHint {
-                            place: Box::new(local.into()),
-                            reason: BackwardIncompatibleDropReason::Edition2024,
-                        },
-                    });
-                } else {
-                    unwind_drops.add_entry_point(block, unwind_to);
-                    let next = cfg.start_new_block();
-                    cfg.terminate(block, source_info, TerminatorKind::Drop {
-                        place: local.into(),
-                        target: next,
-                        unwind: UnwindAction::Continue,
-                        replace: false,
-                    });
-                    block = next;
+                unwind_drops.add_entry_point(block, unwind_to);
+                let next = cfg.start_new_block();
+                cfg.terminate(block, source_info, TerminatorKind::Drop {
+                    place: local.into(),
+                    target: next,
+                    unwind: UnwindAction::Continue,
+                    replace: false,
+                });
+                block = next;
+            }
+            DropKind::ForLint => {
+                // If the operand has been moved, and we are not on an unwind
+                // path, then don't generate the drop. (We only take this into
+                // account for non-unwind paths so as not to disturb the
+                // caching mechanism.)
+                if scope.moved_locals.iter().any(|&o| o == local) {
+                    continue;
+                }
+
+                if storage_dead_on_unwind {
+                    debug_assert_eq!(unwind_drops.drops[unwind_to].data.local, drop_data.local);
+                    debug_assert_eq!(unwind_drops.drops[unwind_to].data.kind, drop_data.kind);
+                    unwind_to = unwind_drops.drops[unwind_to].next;
                 }
+
+                cfg.push(block, Statement {
+                    source_info,
+                    kind: StatementKind::BackwardIncompatibleDropHint {
+                        place: Box::new(local.into()),
+                        reason: BackwardIncompatibleDropReason::Edition2024,
+                    },
+                });
             }
             DropKind::Storage => {
                 if storage_dead_on_unwind {
@@ -1500,7 +1530,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
                             unwind_indices.push(unwind_indices[drop_node.next]);
                         }
                     }
-                    DropKind::Value => {
+                    DropKind::Value | DropKind::ForLint => {
                         let unwind_drop = self
                             .scopes
                             .unwind_drops
diff --git a/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-abort.mir b/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-abort.mir
index 54bedfdc0af..e9bbe30bd77 100644
--- a/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-abort.mir
+++ b/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-abort.mir
@@ -12,10 +12,9 @@ fn method_1(_1: Guard) -> () {
     let _8: OtherDrop;
     let _9: ();
     let mut _10: bool;
-    let mut _11: bool;
+    let mut _11: isize;
     let mut _12: isize;
     let mut _13: isize;
-    let mut _14: isize;
     scope 1 {
         debug other_drop => _8;
     }
@@ -24,7 +23,6 @@ fn method_1(_1: Guard) -> () {
     }
 
     bb0: {
-        _11 = const false;
         _10 = const false;
         StorageLive(_2);
         StorageLive(_3);
@@ -32,15 +30,14 @@ fn method_1(_1: Guard) -> () {
         StorageLive(_5);
         StorageLive(_6);
         _6 = &_1;
-        _5 = <Guard as Clone>::clone(move _6) -> [return: bb1, unwind: bb16];
+        _5 = <Guard as Clone>::clone(move _6) -> [return: bb1, unwind: bb13];
     }
 
     bb1: {
-        _11 = const true;
         StorageDead(_6);
         _4 = &_5;
         _3 = &(*_4);
-        _2 = method_2(move _3) -> [return: bb2, unwind: bb14];
+        _2 = method_2(move _3) -> [return: bb2, unwind: bb12];
     }
 
     bb2: {
@@ -78,20 +75,19 @@ fn method_1(_1: Guard) -> () {
     bb7: {
         backward incompatible drop(_2);
         backward incompatible drop(_5);
-        goto -> bb24;
+        goto -> bb21;
     }
 
     bb8: {
-        drop(_5) -> [return: bb9, unwind: bb16];
+        drop(_5) -> [return: bb9, unwind: bb13];
     }
 
     bb9: {
-        _11 = const false;
         StorageDead(_5);
         StorageDead(_4);
         _10 = const false;
         StorageDead(_2);
-        drop(_1) -> [return: bb10, unwind: bb17];
+        drop(_1) -> [return: bb10, unwind: bb14];
     }
 
     bb10: {
@@ -99,7 +95,7 @@ fn method_1(_1: Guard) -> () {
     }
 
     bb11 (cleanup): {
-        goto -> bb28;
+        goto -> bb25;
     }
 
     bb12 (cleanup): {
@@ -107,77 +103,57 @@ fn method_1(_1: Guard) -> () {
     }
 
     bb13 (cleanup): {
-        goto -> bb15;
+        drop(_1) -> [return: bb14, unwind terminate(cleanup)];
     }
 
     bb14 (cleanup): {
-        drop(_5) -> [return: bb15, unwind terminate(cleanup)];
+        resume;
     }
 
-    bb15 (cleanup): {
-        goto -> bb30;
+    bb15: {
+        goto -> bb8;
     }
 
     bb16 (cleanup): {
-        drop(_1) -> [return: bb17, unwind terminate(cleanup)];
+        goto -> bb12;
     }
 
     bb17 (cleanup): {
-        resume;
+        goto -> bb12;
     }
 
     bb18: {
-        goto -> bb8;
+        goto -> bb15;
     }
 
-    bb19 (cleanup): {
+    bb19: {
         goto -> bb15;
     }
 
     bb20 (cleanup): {
-        goto -> bb15;
+        goto -> bb12;
     }
 
     bb21: {
-        goto -> bb18;
+        _11 = discriminant(_2);
+        switchInt(move _11) -> [0: bb18, otherwise: bb19];
     }
 
-    bb22: {
-        goto -> bb18;
-    }
-
-    bb23 (cleanup): {
-        goto -> bb15;
-    }
-
-    bb24: {
+    bb22 (cleanup): {
         _12 = discriminant(_2);
-        switchInt(move _12) -> [0: bb21, otherwise: bb22];
+        switchInt(move _12) -> [0: bb16, otherwise: bb20];
     }
 
-    bb25 (cleanup): {
-        _13 = discriminant(_2);
-        switchInt(move _13) -> [0: bb19, otherwise: bb23];
-    }
-
-    bb26 (cleanup): {
+    bb23 (cleanup): {
         goto -> bb12;
     }
 
-    bb27 (cleanup): {
+    bb24 (cleanup): {
         goto -> bb12;
     }
 
-    bb28 (cleanup): {
-        _14 = discriminant(_2);
-        switchInt(move _14) -> [0: bb26, otherwise: bb27];
-    }
-
-    bb29 (cleanup): {
-        drop(_5) -> [return: bb16, unwind terminate(cleanup)];
-    }
-
-    bb30 (cleanup): {
-        switchInt(copy _11) -> [0: bb16, otherwise: bb29];
+    bb25 (cleanup): {
+        _13 = discriminant(_2);
+        switchInt(move _13) -> [0: bb23, otherwise: bb24];
     }
 }
diff --git a/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-unwind.mir b/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-unwind.mir
index 54bedfdc0af..e9bbe30bd77 100644
--- a/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-unwind.mir
+++ b/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-unwind.mir
@@ -12,10 +12,9 @@ fn method_1(_1: Guard) -> () {
     let _8: OtherDrop;
     let _9: ();
     let mut _10: bool;
-    let mut _11: bool;
+    let mut _11: isize;
     let mut _12: isize;
     let mut _13: isize;
-    let mut _14: isize;
     scope 1 {
         debug other_drop => _8;
     }
@@ -24,7 +23,6 @@ fn method_1(_1: Guard) -> () {
     }
 
     bb0: {
-        _11 = const false;
         _10 = const false;
         StorageLive(_2);
         StorageLive(_3);
@@ -32,15 +30,14 @@ fn method_1(_1: Guard) -> () {
         StorageLive(_5);
         StorageLive(_6);
         _6 = &_1;
-        _5 = <Guard as Clone>::clone(move _6) -> [return: bb1, unwind: bb16];
+        _5 = <Guard as Clone>::clone(move _6) -> [return: bb1, unwind: bb13];
     }
 
     bb1: {
-        _11 = const true;
         StorageDead(_6);
         _4 = &_5;
         _3 = &(*_4);
-        _2 = method_2(move _3) -> [return: bb2, unwind: bb14];
+        _2 = method_2(move _3) -> [return: bb2, unwind: bb12];
     }
 
     bb2: {
@@ -78,20 +75,19 @@ fn method_1(_1: Guard) -> () {
     bb7: {
         backward incompatible drop(_2);
         backward incompatible drop(_5);
-        goto -> bb24;
+        goto -> bb21;
     }
 
     bb8: {
-        drop(_5) -> [return: bb9, unwind: bb16];
+        drop(_5) -> [return: bb9, unwind: bb13];
     }
 
     bb9: {
-        _11 = const false;
         StorageDead(_5);
         StorageDead(_4);
         _10 = const false;
         StorageDead(_2);
-        drop(_1) -> [return: bb10, unwind: bb17];
+        drop(_1) -> [return: bb10, unwind: bb14];
     }
 
     bb10: {
@@ -99,7 +95,7 @@ fn method_1(_1: Guard) -> () {
     }
 
     bb11 (cleanup): {
-        goto -> bb28;
+        goto -> bb25;
     }
 
     bb12 (cleanup): {
@@ -107,77 +103,57 @@ fn method_1(_1: Guard) -> () {
     }
 
     bb13 (cleanup): {
-        goto -> bb15;
+        drop(_1) -> [return: bb14, unwind terminate(cleanup)];
     }
 
     bb14 (cleanup): {
-        drop(_5) -> [return: bb15, unwind terminate(cleanup)];
+        resume;
     }
 
-    bb15 (cleanup): {
-        goto -> bb30;
+    bb15: {
+        goto -> bb8;
     }
 
     bb16 (cleanup): {
-        drop(_1) -> [return: bb17, unwind terminate(cleanup)];
+        goto -> bb12;
     }
 
     bb17 (cleanup): {
-        resume;
+        goto -> bb12;
     }
 
     bb18: {
-        goto -> bb8;
+        goto -> bb15;
     }
 
-    bb19 (cleanup): {
+    bb19: {
         goto -> bb15;
     }
 
     bb20 (cleanup): {
-        goto -> bb15;
+        goto -> bb12;
     }
 
     bb21: {
-        goto -> bb18;
+        _11 = discriminant(_2);
+        switchInt(move _11) -> [0: bb18, otherwise: bb19];
     }
 
-    bb22: {
-        goto -> bb18;
-    }
-
-    bb23 (cleanup): {
-        goto -> bb15;
-    }
-
-    bb24: {
+    bb22 (cleanup): {
         _12 = discriminant(_2);
-        switchInt(move _12) -> [0: bb21, otherwise: bb22];
+        switchInt(move _12) -> [0: bb16, otherwise: bb20];
     }
 
-    bb25 (cleanup): {
-        _13 = discriminant(_2);
-        switchInt(move _13) -> [0: bb19, otherwise: bb23];
-    }
-
-    bb26 (cleanup): {
+    bb23 (cleanup): {
         goto -> bb12;
     }
 
-    bb27 (cleanup): {
+    bb24 (cleanup): {
         goto -> bb12;
     }
 
-    bb28 (cleanup): {
-        _14 = discriminant(_2);
-        switchInt(move _14) -> [0: bb26, otherwise: bb27];
-    }
-
-    bb29 (cleanup): {
-        drop(_5) -> [return: bb16, unwind terminate(cleanup)];
-    }
-
-    bb30 (cleanup): {
-        switchInt(copy _11) -> [0: bb16, otherwise: bb29];
+    bb25 (cleanup): {
+        _13 = discriminant(_2);
+        switchInt(move _13) -> [0: bb23, otherwise: bb24];
     }
 }
diff --git a/tests/mir-opt/tail_expr_drop_order_unwind.rs b/tests/mir-opt/tail_expr_drop_order_unwind.rs
index b67b3580875..065e08c3409 100644
--- a/tests/mir-opt/tail_expr_drop_order_unwind.rs
+++ b/tests/mir-opt/tail_expr_drop_order_unwind.rs
@@ -26,8 +26,8 @@ fn method_1(g: Guard) {
     match method_2(&g.clone()) {
         Ok(other_drop) => {
             // repro needs something else being dropped too.
-        },
-        Err(err) => {},
+        }
+        Err(err) => {}
     }
 }