88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010
11- use rustc:: ty:: TyCtxt ;
12- use rustc:: mir:: Mir ;
11+ use rustc:: ty:: TypeFoldable ;
12+ use rustc:: ty:: subst:: Substs ;
13+ use rustc:: ty:: { Ty , TyCtxt , ClosureSubsts } ;
14+ use rustc:: mir:: { Mir , Location , Rvalue , BasicBlock , Statement , StatementKind } ;
1315use rustc:: mir:: visit:: MutVisitor ;
1416use rustc:: mir:: transform:: { MirPass , MirSource } ;
17+ use rustc:: infer:: { self , InferCtxt } ;
18+ use syntax_pos:: Span ;
1519
1620#[ allow( dead_code) ]
17- struct NLLVisitor < ' a , ' tcx : ' a > {
18- tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
21+ struct NLLVisitor < ' a , ' gcx : ' a + ' tcx , ' tcx : ' a > {
22+ infcx : InferCtxt < ' a , ' gcx , ' tcx > ,
23+ source : Mir < ' tcx >
1924}
2025
21- impl < ' a , ' tcx > NLLVisitor < ' a , ' tcx > {
22- pub fn new ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ) -> Self {
26+ impl < ' a , ' gcx , ' tcx > NLLVisitor < ' a , ' gcx , ' tcx > {
27+ pub fn new ( infcx : InferCtxt < ' a , ' gcx , ' tcx > , source : Mir < ' tcx > ) -> Self {
2328 NLLVisitor {
24- tcx : tcx
29+ infcx : infcx,
30+ source : source,
2531 }
2632 }
33+
34+ fn renumber_regions < T > ( & self , value : & T , span : Span ) -> T where T : TypeFoldable < ' tcx > {
35+ self . infcx . tcx . fold_regions ( value, & mut false , |_region, _depth| {
36+ self . infcx . next_region_var ( infer:: MiscVariable ( span) )
37+ } )
38+ }
2739}
2840
29- impl < ' a , ' tcx > MutVisitor < ' tcx > for NLLVisitor < ' a , ' tcx > {
30- // FIXME: Nashenas88: implement me!
41+ fn span_from_location < ' tcx > ( source : Mir < ' tcx > , location : Location ) -> Span {
42+ source[ location. block ] . statements [ location. statement_index ] . source_info . span
43+ }
44+
45+ impl < ' a , ' gcx , ' tcx > MutVisitor < ' tcx > for NLLVisitor < ' a , ' gcx , ' tcx > {
46+ fn visit_ty ( & mut self , ty : & mut Ty < ' tcx > ) {
47+ let old_ty = * ty;
48+ // FIXME: Nashenas88 - span should be narrowed down
49+ * ty = self . renumber_regions ( & old_ty, self . source . span ) ;
50+ }
51+
52+ fn visit_substs ( & mut self , substs : & mut & ' tcx Substs < ' tcx > ) {
53+ // FIXME: Nashenas88 - span should be narrowed down
54+ * substs = self . renumber_regions ( & { * substs} , self . source . span ) ;
55+ }
56+
57+ fn visit_rvalue ( & mut self , rvalue : & mut Rvalue < ' tcx > , location : Location ) {
58+ match * rvalue {
59+ Rvalue :: Ref ( ref mut r, _, _) => {
60+ let span = span_from_location ( location) ;
61+ let old_r = * r;
62+ * r = self . renumber_regions ( & old_r, span) ;
63+ }
64+ Rvalue :: Use ( ..) |
65+ Rvalue :: Repeat ( ..) |
66+ Rvalue :: Len ( ..) |
67+ Rvalue :: Cast ( ..) |
68+ Rvalue :: BinaryOp ( ..) |
69+ Rvalue :: CheckedBinaryOp ( ..) |
70+ Rvalue :: UnaryOp ( ..) |
71+ Rvalue :: Discriminant ( ..) |
72+ Rvalue :: NullaryOp ( ..) |
73+ Rvalue :: Aggregate ( ..) => {
74+ // These variants don't contain regions.
75+ }
76+ }
77+ self . super_rvalue ( rvalue, location) ;
78+ }
79+
80+ fn visit_closure_substs ( & mut self ,
81+ substs : & mut ClosureSubsts < ' tcx > ) {
82+ // FIXME: Nashenas88 - span should be narrowed down
83+ * substs = self . renumber_regions ( substs, self . source . span ) ;
84+ }
85+
86+ fn visit_statement ( & mut self ,
87+ block : BasicBlock ,
88+ statement : & mut Statement < ' tcx > ,
89+ location : Location ) {
90+ if let StatementKind :: EndRegion ( _) = statement. kind {
91+ statement. kind = StatementKind :: Nop ;
92+ }
93+ self . super_statement ( block, statement, location) ;
94+ }
3195}
3296
3397// MIR Pass for non-lexical lifetimes
@@ -38,10 +102,16 @@ impl MirPass for NLL {
38102 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
39103 _: MirSource ,
40104 mir : & mut Mir < ' tcx > ) {
41- if tcx. sess . opts . debugging_opts . nll {
105+ if !tcx. sess . opts . debugging_opts . nll {
106+ return ;
107+ }
108+
109+ tcx. infer_ctxt ( ) . enter ( |infcx| {
110+ let mut visitor = NLLVisitor :: new ( infcx, mir. clone ( ) ) ;
42111 // Clone mir so we can mutate it without disturbing the rest
43112 // of the compiler
44- NLLVisitor :: new ( tcx) . visit_mir ( & mut mir. clone ( ) ) ;
45- }
113+ let mut mir = mir. clone ( ) ;
114+ visitor. visit_mir ( & mut mir) ;
115+ } )
46116 }
47117}
0 commit comments