@@ -5,15 +5,21 @@ use rustc_index::bit_set::BitSet;
5
5
use rustc_middle:: mir:: visit:: { PlaceContext , Visitor } ;
6
6
use rustc_middle:: mir:: * ;
7
7
use rustc_middle:: ty:: TyCtxt ;
8
- use rustc_mir_dataflow:: impls:: MaybeStorageLive ;
8
+ use rustc_mir_dataflow:: impls:: { MaybeStorageDead , MaybeStorageLive } ;
9
9
use rustc_mir_dataflow:: storage:: always_storage_live_locals;
10
10
use rustc_mir_dataflow:: { Analysis , ResultsCursor } ;
11
11
use std:: borrow:: Cow ;
12
12
13
13
pub fn lint_body < ' tcx > ( tcx : TyCtxt < ' tcx > , body : & Body < ' tcx > , when : String ) {
14
14
let reachable_blocks = traversal:: reachable_as_bitset ( body) ;
15
15
let always_live_locals = & always_storage_live_locals ( body) ;
16
- let storage_liveness = MaybeStorageLive :: new ( Cow :: Borrowed ( always_live_locals) )
16
+
17
+ let maybe_storage_live = MaybeStorageLive :: new ( Cow :: Borrowed ( always_live_locals) )
18
+ . into_engine ( tcx, body)
19
+ . iterate_to_fixpoint ( )
20
+ . into_results_cursor ( body) ;
21
+
22
+ let maybe_storage_dead = MaybeStorageDead :: new ( Cow :: Borrowed ( always_live_locals) )
17
23
. into_engine ( tcx, body)
18
24
. iterate_to_fixpoint ( )
19
25
. into_results_cursor ( body) ;
@@ -25,7 +31,8 @@ pub fn lint_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, when: String) {
25
31
is_fn_like : tcx. def_kind ( body. source . def_id ( ) ) . is_fn_like ( ) ,
26
32
always_live_locals,
27
33
reachable_blocks,
28
- storage_liveness,
34
+ maybe_storage_live,
35
+ maybe_storage_dead,
29
36
}
30
37
. visit_body ( body) ;
31
38
}
@@ -37,7 +44,8 @@ struct Lint<'a, 'tcx> {
37
44
is_fn_like : bool ,
38
45
always_live_locals : & ' a BitSet < Local > ,
39
46
reachable_blocks : BitSet < BasicBlock > ,
40
- storage_liveness : ResultsCursor < ' a , ' tcx , MaybeStorageLive < ' a > > ,
47
+ maybe_storage_live : ResultsCursor < ' a , ' tcx , MaybeStorageLive < ' a > > ,
48
+ maybe_storage_dead : ResultsCursor < ' a , ' tcx , MaybeStorageDead < ' a > > ,
41
49
}
42
50
43
51
impl < ' a , ' tcx > Lint < ' a , ' tcx > {
@@ -60,8 +68,8 @@ impl<'a, 'tcx> Lint<'a, 'tcx> {
60
68
impl < ' a , ' tcx > Visitor < ' tcx > for Lint < ' a , ' tcx > {
61
69
fn visit_local ( & mut self , local : Local , context : PlaceContext , location : Location ) {
62
70
if self . reachable_blocks . contains ( location. block ) && context. is_use ( ) {
63
- self . storage_liveness . seek_after_primary_effect ( location) ;
64
- if ! self . storage_liveness . get ( ) . contains ( local) {
71
+ self . maybe_storage_dead . seek_after_primary_effect ( location) ;
72
+ if self . maybe_storage_dead . get ( ) . contains ( local) {
65
73
self . fail ( location, format ! ( "use of local {local:?}, which has no storage here" ) ) ;
66
74
}
67
75
}
@@ -71,8 +79,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Lint<'a, 'tcx> {
71
79
match statement. kind {
72
80
StatementKind :: StorageLive ( local) => {
73
81
if self . reachable_blocks . contains ( location. block ) {
74
- self . storage_liveness . seek_before_primary_effect ( location) ;
75
- if self . storage_liveness . get ( ) . contains ( local) {
82
+ self . maybe_storage_live . seek_before_primary_effect ( location) ;
83
+ if self . maybe_storage_live . get ( ) . contains ( local) {
76
84
self . fail (
77
85
location,
78
86
format ! ( "StorageLive({local:?}) which already has storage here" ) ,
@@ -90,8 +98,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Lint<'a, 'tcx> {
90
98
match terminator. kind {
91
99
TerminatorKind :: Return => {
92
100
if self . is_fn_like && self . reachable_blocks . contains ( location. block ) {
93
- self . storage_liveness . seek_after_primary_effect ( location) ;
94
- for local in self . storage_liveness . get ( ) . iter ( ) {
101
+ self . maybe_storage_live . seek_after_primary_effect ( location) ;
102
+ for local in self . maybe_storage_live . get ( ) . iter ( ) {
95
103
if !self . always_live_locals . contains ( local) {
96
104
self . fail (
97
105
location,
0 commit comments