@@ -151,15 +151,13 @@ struct DropData {
151151
152152 /// Whether this is a value Drop or a StorageDead.
153153 kind : DropKind ,
154-
155- /// Whether this is a backwards-incompatible drop lint
156- backwards_incompatible_lint : bool ,
157154}
158155
159156#[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
160157pub ( crate ) enum DropKind {
161158 Value ,
162159 Storage ,
160+ ForLint ,
163161}
164162
165163#[ derive( Debug ) ]
@@ -248,7 +246,7 @@ impl Scope {
248246 /// use of optimizations in the MIR coroutine transform.
249247 fn needs_cleanup ( & self ) -> bool {
250248 self . drops . iter ( ) . any ( |drop| match drop. kind {
251- DropKind :: Value => true ,
249+ DropKind :: Value | DropKind :: ForLint => true ,
252250 DropKind :: Storage => false ,
253251 } )
254252 }
@@ -277,12 +275,8 @@ impl DropTree {
277275 // represents the block in the tree that should be jumped to once all
278276 // of the required drops have been performed.
279277 let fake_source_info = SourceInfo :: outermost ( DUMMY_SP ) ;
280- let fake_data = DropData {
281- source_info : fake_source_info,
282- local : Local :: MAX ,
283- kind : DropKind :: Storage ,
284- backwards_incompatible_lint : false ,
285- } ;
278+ let fake_data =
279+ DropData { source_info : fake_source_info, local : Local :: MAX , kind : DropKind :: Storage } ;
286280 let drops = IndexVec :: from_raw ( vec ! [ DropNode { data: fake_data, next: DropIdx :: MAX } ] ) ;
287281 Self { drops, entry_points : Vec :: new ( ) , existing_drops_map : FxHashMap :: default ( ) }
288282 }
@@ -411,6 +405,27 @@ impl DropTree {
411405 } ;
412406 cfg. terminate ( block, drop_node. data . source_info , terminator) ;
413407 }
408+ DropKind :: ForLint => {
409+ let stmt = Statement {
410+ source_info : drop_node. data . source_info ,
411+ kind : StatementKind :: BackwardIncompatibleDropHint {
412+ place : Box :: new ( drop_node. data . local . into ( ) ) ,
413+ reason : BackwardIncompatibleDropReason :: Edition2024 ,
414+ } ,
415+ } ;
416+ cfg. push ( block, stmt) ;
417+ let target = blocks[ drop_node. next ] . unwrap ( ) ;
418+ if target != block {
419+ // Diagnostics don't use this `Span` but debuginfo
420+ // might. Since we don't want breakpoints to be placed
421+ // here, especially when this is on an unwind path, we
422+ // use `DUMMY_SP`.
423+ let source_info =
424+ SourceInfo { span : DUMMY_SP , ..drop_node. data . source_info } ;
425+ let terminator = TerminatorKind :: Goto { target } ;
426+ cfg. terminate ( block, source_info, terminator) ;
427+ }
428+ }
414429 // Root nodes don't correspond to a drop.
415430 DropKind :: Storage if drop_idx == ROOT_NODE => { }
416431 DropKind :: Storage => {
@@ -770,12 +785,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
770785 let local =
771786 place. as_local ( ) . unwrap_or_else ( || bug ! ( "projection in tail call args" ) ) ;
772787
773- Some ( DropData {
774- source_info,
775- local,
776- kind : DropKind :: Value ,
777- backwards_incompatible_lint : false ,
778- } )
788+ Some ( DropData { source_info, local, kind : DropKind :: Value } )
779789 }
780790 Operand :: Constant ( _) => None ,
781791 } )
@@ -822,6 +832,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
822832 } ) ;
823833 block = next;
824834 }
835+ DropKind :: ForLint => {
836+ self . cfg . push ( block, Statement {
837+ source_info,
838+ kind : StatementKind :: BackwardIncompatibleDropHint {
839+ place : Box :: new ( local. into ( ) ) ,
840+ reason : BackwardIncompatibleDropReason :: Edition2024 ,
841+ } ,
842+ } ) ;
843+ }
825844 DropKind :: Storage => {
826845 // Only temps and vars need their storage dead.
827846 assert ! ( local. index( ) > self . arg_count) ;
@@ -1021,7 +1040,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
10211040 drop_kind : DropKind ,
10221041 ) {
10231042 let needs_drop = match drop_kind {
1024- DropKind :: Value => {
1043+ DropKind :: Value | DropKind :: ForLint => {
10251044 if !self . local_decls [ local] . ty . needs_drop ( self . tcx , self . typing_env ( ) ) {
10261045 return ;
10271046 }
@@ -1101,7 +1120,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
11011120 source_info : SourceInfo { span : scope_end, scope : scope. source_scope } ,
11021121 local,
11031122 kind : drop_kind,
1104- backwards_incompatible_lint : false ,
11051123 } ) ;
11061124
11071125 return ;
@@ -1135,8 +1153,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
11351153 scope. drops . push ( DropData {
11361154 source_info : SourceInfo { span : scope_end, scope : scope. source_scope } ,
11371155 local,
1138- kind : DropKind :: Value ,
1139- backwards_incompatible_lint : true ,
1156+ kind : DropKind :: ForLint ,
11401157 } ) ;
11411158
11421159 return ;
@@ -1430,25 +1447,38 @@ fn build_scope_drops<'tcx>(
14301447 continue ;
14311448 }
14321449
1433- if drop_data. backwards_incompatible_lint {
1434- cfg. push ( block, Statement {
1435- source_info,
1436- kind : StatementKind :: BackwardIncompatibleDropHint {
1437- place : Box :: new ( local. into ( ) ) ,
1438- reason : BackwardIncompatibleDropReason :: Edition2024 ,
1439- } ,
1440- } ) ;
1441- } else {
1442- unwind_drops. add_entry_point ( block, unwind_to) ;
1443- let next = cfg. start_new_block ( ) ;
1444- cfg. terminate ( block, source_info, TerminatorKind :: Drop {
1445- place : local. into ( ) ,
1446- target : next,
1447- unwind : UnwindAction :: Continue ,
1448- replace : false ,
1449- } ) ;
1450- block = next;
1450+ unwind_drops. add_entry_point ( block, unwind_to) ;
1451+ let next = cfg. start_new_block ( ) ;
1452+ cfg. terminate ( block, source_info, TerminatorKind :: Drop {
1453+ place : local. into ( ) ,
1454+ target : next,
1455+ unwind : UnwindAction :: Continue ,
1456+ replace : false ,
1457+ } ) ;
1458+ block = next;
1459+ }
1460+ DropKind :: ForLint => {
1461+ // If the operand has been moved, and we are not on an unwind
1462+ // path, then don't generate the drop. (We only take this into
1463+ // account for non-unwind paths so as not to disturb the
1464+ // caching mechanism.)
1465+ if scope. moved_locals . iter ( ) . any ( |& o| o == local) {
1466+ continue ;
1467+ }
1468+
1469+ if storage_dead_on_unwind {
1470+ debug_assert_eq ! ( unwind_drops. drops[ unwind_to] . data. local, drop_data. local) ;
1471+ debug_assert_eq ! ( unwind_drops. drops[ unwind_to] . data. kind, drop_data. kind) ;
1472+ unwind_to = unwind_drops. drops [ unwind_to] . next ;
14511473 }
1474+
1475+ cfg. push ( block, Statement {
1476+ source_info,
1477+ kind : StatementKind :: BackwardIncompatibleDropHint {
1478+ place : Box :: new ( local. into ( ) ) ,
1479+ reason : BackwardIncompatibleDropReason :: Edition2024 ,
1480+ } ,
1481+ } ) ;
14521482 }
14531483 DropKind :: Storage => {
14541484 if storage_dead_on_unwind {
@@ -1500,7 +1530,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
15001530 unwind_indices. push ( unwind_indices[ drop_node. next ] ) ;
15011531 }
15021532 }
1503- DropKind :: Value => {
1533+ DropKind :: Value | DropKind :: ForLint => {
15041534 let unwind_drop = self
15051535 . scopes
15061536 . unwind_drops
0 commit comments