@@ -5,15 +5,21 @@ use rustc_index::bit_set::BitSet;
55use rustc_middle:: mir:: visit:: { PlaceContext , Visitor } ;
66use rustc_middle:: mir:: * ;
77use rustc_middle:: ty:: TyCtxt ;
8- use rustc_mir_dataflow:: impls:: MaybeStorageLive ;
8+ use rustc_mir_dataflow:: impls:: { MaybeStorageDead , MaybeStorageLive } ;
99use rustc_mir_dataflow:: storage:: always_storage_live_locals;
1010use rustc_mir_dataflow:: { Analysis , ResultsCursor } ;
1111use std:: borrow:: Cow ;
1212
1313pub fn lint_body < ' tcx > ( tcx : TyCtxt < ' tcx > , body : & Body < ' tcx > , when : String ) {
1414 let reachable_blocks = traversal:: reachable_as_bitset ( body) ;
1515 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) )
1723 . into_engine ( tcx, body)
1824 . iterate_to_fixpoint ( )
1925 . into_results_cursor ( body) ;
@@ -25,7 +31,8 @@ pub fn lint_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, when: String) {
2531 is_fn_like : tcx. def_kind ( body. source . def_id ( ) ) . is_fn_like ( ) ,
2632 always_live_locals,
2733 reachable_blocks,
28- storage_liveness,
34+ maybe_storage_live,
35+ maybe_storage_dead,
2936 }
3037 . visit_body ( body) ;
3138}
@@ -37,7 +44,8 @@ struct Lint<'a, 'tcx> {
3744 is_fn_like : bool ,
3845 always_live_locals : & ' a BitSet < Local > ,
3946 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 > > ,
4149}
4250
4351impl < ' a , ' tcx > Lint < ' a , ' tcx > {
@@ -60,8 +68,8 @@ impl<'a, 'tcx> Lint<'a, 'tcx> {
6068impl < ' a , ' tcx > Visitor < ' tcx > for Lint < ' a , ' tcx > {
6169 fn visit_local ( & mut self , local : Local , context : PlaceContext , location : Location ) {
6270 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) {
6573 self . fail ( location, format ! ( "use of local {local:?}, which has no storage here" ) ) ;
6674 }
6775 }
@@ -71,8 +79,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Lint<'a, 'tcx> {
7179 match statement. kind {
7280 StatementKind :: StorageLive ( local) => {
7381 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) {
7684 self . fail (
7785 location,
7886 format ! ( "StorageLive({local:?}) which already has storage here" ) ,
@@ -90,8 +98,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Lint<'a, 'tcx> {
9098 match terminator. kind {
9199 TerminatorKind :: Return => {
92100 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 ( ) {
95103 if !self . always_live_locals . contains ( local) {
96104 self . fail (
97105 location,
0 commit comments