@@ -12,19 +12,19 @@ use rustc::ty::TypeFoldable;
12
12
use rustc:: ty:: subst:: Substs ;
13
13
use rustc:: ty:: { Ty , TyCtxt , ClosureSubsts } ;
14
14
use rustc:: mir:: { Mir , Location , Rvalue , BasicBlock , Statement , StatementKind } ;
15
- use rustc:: mir:: visit:: MutVisitor ;
15
+ use rustc:: mir:: visit:: { MutVisitor , Lookup } ;
16
16
use rustc:: mir:: transform:: { MirPass , MirSource } ;
17
17
use rustc:: infer:: { self , InferCtxt } ;
18
18
use syntax_pos:: Span ;
19
19
20
20
#[ allow( dead_code) ]
21
21
struct NLLVisitor < ' a , ' gcx : ' a + ' tcx , ' tcx : ' a > {
22
22
infcx : InferCtxt < ' a , ' gcx , ' tcx > ,
23
- source : Mir < ' tcx >
23
+ source : & ' a Mir < ' tcx >
24
24
}
25
25
26
26
impl < ' a , ' gcx , ' tcx > NLLVisitor < ' a , ' gcx , ' tcx > {
27
- pub fn new ( infcx : InferCtxt < ' a , ' gcx , ' tcx > , source : Mir < ' tcx > ) -> Self {
27
+ pub fn new ( infcx : InferCtxt < ' a , ' gcx , ' tcx > , source : & ' a Mir < ' tcx > ) -> Self {
28
28
NLLVisitor {
29
29
infcx : infcx,
30
30
source : source,
@@ -38,28 +38,29 @@ impl<'a, 'gcx, 'tcx> NLLVisitor<'a, 'gcx, 'tcx> {
38
38
}
39
39
}
40
40
41
- fn span_from_location < ' tcx > ( source : Mir < ' tcx > , location : Location ) -> Span {
41
+ fn span_from_location < ' tcx > ( source : & Mir < ' tcx > , location : Location ) -> Span {
42
42
source[ location. block ] . statements [ location. statement_index ] . source_info . span
43
43
}
44
44
45
45
impl < ' a , ' gcx , ' tcx > MutVisitor < ' tcx > for NLLVisitor < ' a , ' gcx , ' tcx > {
46
- fn visit_ty ( & mut self , ty : & mut Ty < ' tcx > ) {
46
+ fn visit_ty ( & mut self , ty : & mut Ty < ' tcx > , lookup : Lookup ) {
47
47
let old_ty = * ty;
48
- // FIXME: Nashenas88 - span should be narrowed down
49
- * ty = self . renumber_regions ( & old_ty, self . source . span ) ;
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) ;
50
53
}
51
54
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
+ fn visit_substs ( & mut self , substs : & mut & ' tcx Substs < ' tcx > , location : Location ) {
56
+ * substs = self . renumber_regions ( & { * substs} , span_from_location ( self . source , location) ) ;
55
57
}
56
58
57
59
fn visit_rvalue ( & mut self , rvalue : & mut Rvalue < ' tcx > , location : Location ) {
58
60
match * rvalue {
59
61
Rvalue :: Ref ( ref mut r, _, _) => {
60
- let span = span_from_location ( location) ;
61
62
let old_r = * r;
62
- * r = self . renumber_regions ( & old_r, span ) ;
63
+ * r = self . renumber_regions ( & old_r, span_from_location ( self . source , location ) ) ;
63
64
}
64
65
Rvalue :: Use ( ..) |
65
66
Rvalue :: Repeat ( ..) |
@@ -78,9 +79,9 @@ impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> {
78
79
}
79
80
80
81
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 ) ;
82
+ substs : & mut ClosureSubsts < ' tcx > ,
83
+ location : Location ) {
84
+ * substs = self . renumber_regions ( substs, span_from_location ( self . source , location ) ) ;
84
85
}
85
86
86
87
fn visit_statement ( & mut self ,
@@ -107,11 +108,15 @@ impl MirPass for NLL {
107
108
}
108
109
109
110
tcx. infer_ctxt ( ) . enter ( |infcx| {
110
- let mut visitor = NLLVisitor :: new ( infcx, mir. clone ( ) ) ;
111
111
// Clone mir so we can mutate it without disturbing the rest
112
112
// of the compiler
113
- let mut mir = mir. clone ( ) ;
114
- visitor. visit_mir ( & mut mir) ;
113
+ 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) ;
119
+ visitor. visit_mir ( & mut renumbered_mir) ;
115
120
} )
116
121
}
117
122
}
0 commit comments