@@ -28,13 +28,20 @@ fn place_has_common_prefix<'tcx>(left: &Place<'tcx>, right: &Place<'tcx>) -> boo
28
28
&& left. projection . iter ( ) . zip ( right. projection ) . all ( |( left, right) | left == right)
29
29
}
30
30
31
+ #[ derive( Debug , Clone , Copy ) ]
32
+ enum MovePathIndexAtBlock {
33
+ Unknown ,
34
+ None ,
35
+ Some ( MovePathIndex ) ,
36
+ }
37
+
31
38
struct DropsReachable < ' a , ' mir , ' tcx > {
32
39
body : & ' a Body < ' tcx > ,
33
40
place : & ' a Place < ' tcx > ,
34
41
drop_span : & ' a mut Option < Span > ,
35
42
move_data : & ' a MoveData < ' tcx > ,
36
43
maybe_init : & ' a mut ResultsCursor < ' mir , ' tcx , MaybeInitializedPlaces < ' mir , ' tcx > > ,
37
- block_drop_value_info : & ' a mut IndexSlice < BasicBlock , Option < MovePathIndex > > ,
44
+ block_drop_value_info : & ' a mut IndexSlice < BasicBlock , MovePathIndexAtBlock > ,
38
45
collected_drops : & ' a mut ChunkedBitSet < MovePathIndex > ,
39
46
visited : FxHashMap < BasicBlock , Rc < RefCell < ChunkedBitSet < MovePathIndex > > > > ,
40
47
}
@@ -53,27 +60,35 @@ impl<'a, 'mir, 'tcx> DropsReachable<'a, 'mir, 'tcx> {
53
60
self . visited . entry ( block) . or_insert_with ( make_new_path_set) . clone ( ) ;
54
61
// We could have invoked reverse lookup for a `MovePathIndex` every time, but unfortunately it is expensive.
55
62
// Let's cache them in `self.block_drop_value_info`.
56
- if let Some ( dropped) = self . block_drop_value_info [ block] {
57
- dropped_local_here. borrow_mut ( ) . insert ( dropped) ;
58
- } else if let TerminatorKind :: Drop { place, .. } = & terminator. kind
59
- && let LookupResult :: Exact ( idx) | LookupResult :: Parent ( Some ( idx) ) =
60
- self . move_data . rev_lookup . find ( place. as_ref ( ) )
61
- {
62
- // Since we are working with MIRs at a very early stage,
63
- // observing a `drop` terminator is not indicative enough that
64
- // the drop will definitely happen.
65
- // That is decided in the drop elaboration pass instead.
66
- // Therefore, we need to consult with the maybe-initialization information.
67
- self . maybe_init . seek_before_primary_effect ( Location {
68
- block,
69
- statement_index : data. statements . len ( ) ,
70
- } ) ;
71
- if let MaybeReachable :: Reachable ( maybe_init) = self . maybe_init . get ( )
72
- && maybe_init. contains ( idx)
73
- {
74
- self . block_drop_value_info [ block] = Some ( idx) ;
75
- dropped_local_here. borrow_mut ( ) . insert ( idx) ;
63
+ match self . block_drop_value_info [ block] {
64
+ MovePathIndexAtBlock :: Some ( dropped) => {
65
+ dropped_local_here. borrow_mut ( ) . insert ( dropped) ;
66
+ }
67
+ MovePathIndexAtBlock :: Unknown => {
68
+ if let TerminatorKind :: Drop { place, .. } = & terminator. kind
69
+ && let LookupResult :: Exact ( idx) | LookupResult :: Parent ( Some ( idx) ) =
70
+ self . move_data . rev_lookup . find ( place. as_ref ( ) )
71
+ {
72
+ // Since we are working with MIRs at a very early stage,
73
+ // observing a `drop` terminator is not indicative enough that
74
+ // the drop will definitely happen.
75
+ // That is decided in the drop elaboration pass instead.
76
+ // Therefore, we need to consult with the maybe-initialization information.
77
+ self . maybe_init . seek_before_primary_effect ( Location {
78
+ block,
79
+ statement_index : data. statements . len ( ) ,
80
+ } ) ;
81
+ if let MaybeReachable :: Reachable ( maybe_init) = self . maybe_init . get ( )
82
+ && maybe_init. contains ( idx)
83
+ {
84
+ self . block_drop_value_info [ block] = MovePathIndexAtBlock :: Some ( idx) ;
85
+ dropped_local_here. borrow_mut ( ) . insert ( idx) ;
86
+ } else {
87
+ self . block_drop_value_info [ block] = MovePathIndexAtBlock :: None ;
88
+ }
89
+ }
76
90
}
91
+ MovePathIndexAtBlock :: None => { }
77
92
}
78
93
79
94
for succ in terminator. successors ( ) {
@@ -283,7 +298,8 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
283
298
let move_data = MoveData :: gather_moves ( body, tcx, |_| true ) ;
284
299
let maybe_init = MaybeInitializedPlaces :: new ( tcx, body, & move_data) ;
285
300
let mut maybe_init = maybe_init. iterate_to_fixpoint ( tcx, body, None ) . into_results_cursor ( body) ;
286
- let mut block_drop_value_info = IndexVec :: from_elem_n ( None , body. basic_blocks . len ( ) ) ;
301
+ let mut block_drop_value_info =
302
+ IndexVec :: from_elem_n ( MovePathIndexAtBlock :: Unknown , body. basic_blocks . len ( ) ) ;
287
303
for ( & block, candidates) in & bid_per_block {
288
304
let mut all_locals_dropped = ChunkedBitSet :: new_empty ( move_data. move_paths . len ( ) ) ;
289
305
let mut drop_span = None ;
0 commit comments