@@ -151,15 +151,13 @@ struct DropData {
151
151
152
152
/// Whether this is a value Drop or a StorageDead.
153
153
kind : DropKind ,
154
-
155
- /// Whether this is a backwards-incompatible drop lint
156
- backwards_incompatible_lint : bool ,
157
154
}
158
155
159
156
#[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
160
157
pub ( crate ) enum DropKind {
161
158
Value ,
162
159
Storage ,
160
+ ForLint ,
163
161
}
164
162
165
163
#[ derive( Debug ) ]
@@ -248,7 +246,7 @@ impl Scope {
248
246
/// use of optimizations in the MIR coroutine transform.
249
247
fn needs_cleanup ( & self ) -> bool {
250
248
self . drops . iter ( ) . any ( |drop| match drop. kind {
251
- DropKind :: Value => true ,
249
+ DropKind :: Value | DropKind :: ForLint => true ,
252
250
DropKind :: Storage => false ,
253
251
} )
254
252
}
@@ -277,12 +275,8 @@ impl DropTree {
277
275
// represents the block in the tree that should be jumped to once all
278
276
// of the required drops have been performed.
279
277
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 } ;
286
280
let drops = IndexVec :: from_raw ( vec ! [ DropNode { data: fake_data, next: DropIdx :: MAX } ] ) ;
287
281
Self { drops, entry_points : Vec :: new ( ) , existing_drops_map : FxHashMap :: default ( ) }
288
282
}
@@ -411,6 +405,27 @@ impl DropTree {
411
405
} ;
412
406
cfg. terminate ( block, drop_node. data . source_info , terminator) ;
413
407
}
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
+ }
414
429
// Root nodes don't correspond to a drop.
415
430
DropKind :: Storage if drop_idx == ROOT_NODE => { }
416
431
DropKind :: Storage => {
@@ -770,12 +785,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
770
785
let local =
771
786
place. as_local ( ) . unwrap_or_else ( || bug ! ( "projection in tail call args" ) ) ;
772
787
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 } )
779
789
}
780
790
Operand :: Constant ( _) => None ,
781
791
} )
@@ -822,6 +832,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
822
832
} ) ;
823
833
block = next;
824
834
}
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
+ }
825
844
DropKind :: Storage => {
826
845
// Only temps and vars need their storage dead.
827
846
assert ! ( local. index( ) > self . arg_count) ;
@@ -1021,7 +1040,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1021
1040
drop_kind : DropKind ,
1022
1041
) {
1023
1042
let needs_drop = match drop_kind {
1024
- DropKind :: Value => {
1043
+ DropKind :: Value | DropKind :: ForLint => {
1025
1044
if !self . local_decls [ local] . ty . needs_drop ( self . tcx , self . typing_env ( ) ) {
1026
1045
return ;
1027
1046
}
@@ -1101,7 +1120,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1101
1120
source_info : SourceInfo { span : scope_end, scope : scope. source_scope } ,
1102
1121
local,
1103
1122
kind : drop_kind,
1104
- backwards_incompatible_lint : false ,
1105
1123
} ) ;
1106
1124
1107
1125
return ;
@@ -1135,8 +1153,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1135
1153
scope. drops . push ( DropData {
1136
1154
source_info : SourceInfo { span : scope_end, scope : scope. source_scope } ,
1137
1155
local,
1138
- kind : DropKind :: Value ,
1139
- backwards_incompatible_lint : true ,
1156
+ kind : DropKind :: ForLint ,
1140
1157
} ) ;
1141
1158
1142
1159
return ;
@@ -1430,25 +1447,38 @@ fn build_scope_drops<'tcx>(
1430
1447
continue ;
1431
1448
}
1432
1449
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 ;
1451
1473
}
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
+ } ) ;
1452
1482
}
1453
1483
DropKind :: Storage => {
1454
1484
if storage_dead_on_unwind {
@@ -1500,7 +1530,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
1500
1530
unwind_indices. push ( unwind_indices[ drop_node. next ] ) ;
1501
1531
}
1502
1532
}
1503
- DropKind :: Value => {
1533
+ DropKind :: Value | DropKind :: ForLint => {
1504
1534
let unwind_drop = self
1505
1535
. scopes
1506
1536
. unwind_drops
0 commit comments