8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
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 } ;
13
15
use rustc:: mir:: visit:: MutVisitor ;
14
16
use rustc:: mir:: transform:: { MirPass , MirSource } ;
17
+ use rustc:: infer:: { self , InferCtxt } ;
18
+ use syntax_pos:: Span ;
15
19
16
20
#[ 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 >
19
24
}
20
25
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 {
23
28
NLLVisitor {
24
- tcx : tcx
29
+ infcx : infcx,
30
+ source : source,
25
31
}
26
32
}
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
+ }
27
39
}
28
40
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
+ }
31
95
}
32
96
33
97
// MIR Pass for non-lexical lifetimes
@@ -38,10 +102,16 @@ impl MirPass for NLL {
38
102
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
39
103
_: MirSource ,
40
104
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 ( ) ) ;
42
111
// Clone mir so we can mutate it without disturbing the rest
43
112
// 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
+ } )
46
116
}
47
117
}
0 commit comments