99// except according to those terms.
1010
1111use rustc:: ty:: TypeFoldable ;
12- use rustc:: ty:: subst:: Substs ;
13- use rustc:: ty:: { Ty , TyCtxt , ClosureSubsts } ;
12+ use rustc:: ty:: subst:: { Kind , Substs } ;
13+ use rustc:: ty:: { Ty , TyCtxt , ClosureSubsts , RegionVid , RegionKind } ;
1414use rustc:: mir:: { Mir , Location , Rvalue , BasicBlock , Statement , StatementKind } ;
1515use rustc:: mir:: visit:: { MutVisitor , Lookup } ;
1616use rustc:: mir:: transform:: { MirPass , MirSource } ;
1717use rustc:: infer:: { self , InferCtxt } ;
18- use syntax_pos:: Span ;
18+ use syntax_pos:: DUMMY_SP ;
19+ use std:: collections:: HashMap ;
1920
2021#[ allow( dead_code) ]
2122struct NLLVisitor < ' a , ' gcx : ' a + ' tcx , ' tcx : ' a > {
23+ pub lookup_map : HashMap < RegionVid , Lookup > ,
2224 infcx : InferCtxt < ' a , ' gcx , ' tcx > ,
23- source : & ' a Mir < ' tcx >
2425}
2526
2627impl < ' a , ' gcx , ' tcx > NLLVisitor < ' a , ' gcx , ' tcx > {
27- pub fn new ( infcx : InferCtxt < ' a , ' gcx , ' tcx > , source : & ' a Mir < ' tcx > ) -> Self {
28+ pub fn new ( infcx : InferCtxt < ' a , ' gcx , ' tcx > ) -> Self {
2829 NLLVisitor {
2930 infcx : infcx,
30- source : source ,
31+ lookup_map : HashMap :: new ( ) ,
3132 }
3233 }
3334
34- fn renumber_regions < T > ( & self , value : & T , span : Span ) -> T where T : TypeFoldable < ' tcx > {
35+ fn renumber_regions < T > ( & self , value : & T ) -> T where T : TypeFoldable < ' tcx > {
3536 self . infcx . tcx . fold_regions ( value, & mut false , |_region, _depth| {
36- self . infcx . next_region_var ( infer:: MiscVariable ( span ) )
37+ self . infcx . next_region_var ( infer:: MiscVariable ( DUMMY_SP ) )
3738 } )
3839 }
39- }
4040
41- fn span_from_location < ' tcx > ( source : & Mir < ' tcx > , location : Location ) -> Span {
42- source[ location. block ] . statements [ location. statement_index ] . source_info . span
41+ fn store_region ( & mut self , region : & RegionKind , lookup : Lookup ) {
42+ if let RegionKind :: ReVar ( rid) = * region {
43+ self . lookup_map . entry ( rid) . or_insert ( lookup) ;
44+ }
45+ }
46+
47+ fn store_ty_regions ( & mut self , ty : & Ty < ' tcx > , lookup : Lookup ) {
48+ for region in ty. regions ( ) {
49+ self . store_region ( region, lookup) ;
50+ }
51+ }
52+
53+ fn store_kind_regions ( & mut self , kind : & ' tcx Kind , lookup : Lookup ) {
54+ if let Some ( ty) = kind. as_type ( ) {
55+ self . store_ty_regions ( & ty, lookup) ;
56+ } else if let Some ( region) = kind. as_region ( ) {
57+ self . store_region ( region, lookup) ;
58+ }
59+ }
4360}
4461
4562impl < ' a , ' gcx , ' tcx > MutVisitor < ' tcx > for NLLVisitor < ' a , ' gcx , ' tcx > {
4663 fn visit_ty ( & mut self , ty : & mut Ty < ' tcx > , lookup : Lookup ) {
4764 let old_ty = * ty;
48- let span = match lookup {
49- Lookup :: Loc ( location) => span_from_location ( self . source , location) ,
50- Lookup :: Src ( source_info) => source_info. span ,
51- } ;
52- * ty = self . renumber_regions ( & old_ty, span) ;
65+ * ty = self . renumber_regions ( & old_ty) ;
66+ self . store_ty_regions ( ty, lookup) ;
5367 }
5468
5569 fn visit_substs ( & mut self , substs : & mut & ' tcx Substs < ' tcx > , location : Location ) {
56- * substs = self . renumber_regions ( & { * substs} , span_from_location ( self . source , location) ) ;
70+ * substs = self . renumber_regions ( & { * substs} ) ;
71+ let lookup = Lookup :: Loc ( location) ;
72+ for kind in * substs {
73+ self . store_kind_regions ( kind, lookup) ;
74+ }
5775 }
5876
5977 fn visit_rvalue ( & mut self , rvalue : & mut Rvalue < ' tcx > , location : Location ) {
6078 match * rvalue {
6179 Rvalue :: Ref ( ref mut r, _, _) => {
6280 let old_r = * r;
63- * r = self . renumber_regions ( & old_r, span_from_location ( self . source , location) ) ;
81+ * r = self . renumber_regions ( & old_r) ;
82+ let lookup = Lookup :: Loc ( location) ;
83+ self . store_region ( r, lookup) ;
6484 }
6585 Rvalue :: Use ( ..) |
6686 Rvalue :: Repeat ( ..) |
@@ -81,7 +101,11 @@ impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> {
81101 fn visit_closure_substs ( & mut self ,
82102 substs : & mut ClosureSubsts < ' tcx > ,
83103 location : Location ) {
84- * substs = self . renumber_regions ( substs, span_from_location ( self . source , location) ) ;
104+ * substs = self . renumber_regions ( substs) ;
105+ let lookup = Lookup :: Loc ( location) ;
106+ for kind in substs. substs {
107+ self . store_kind_regions ( kind, lookup) ;
108+ }
85109 }
86110
87111 fn visit_statement ( & mut self ,
@@ -108,14 +132,9 @@ impl MirPass for NLL {
108132 }
109133
110134 tcx. infer_ctxt ( ) . enter ( |infcx| {
111- // Clone mir so we can mutate it without disturbing the rest
112- // of the compiler
135+ // Clone mir so we can mutate it without disturbing the rest of the compiler
113136 let mut renumbered_mir = mir. clone ( ) ;
114-
115- // Note that we're using the passed-in mir for the visitor. This is
116- // so we can lookup locations during traversal without worrying about
117- // maintaing both a mutable and immutable reference to the same object
118- let mut visitor = NLLVisitor :: new ( infcx, & mir) ;
137+ let mut visitor = NLLVisitor :: new ( infcx) ;
119138 visitor. visit_mir ( & mut renumbered_mir) ;
120139 } )
121140 }
0 commit comments