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:: { self , TyCtxt } ;
11
+ use rustc:: ty:: { self , Ty , TyCtxt } ;
12
12
use rustc:: mir:: * ;
13
- use rustc:: mir:: tcx:: RvalueInitializationState ;
13
+ use rustc:: mir:: tcx:: { PlaceTy , RvalueInitializationState } ;
14
14
use rustc:: util:: nodemap:: FxHashMap ;
15
15
use rustc_data_structures:: indexed_vec:: { IndexVec } ;
16
16
@@ -107,18 +107,23 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
107
107
{
108
108
debug ! ( "lookup({:?})" , place) ;
109
109
let mut result = match place. base {
110
- PlaceBase :: Local ( local) => Ok ( self . builder . data . rev_lookup . locals [ local] ) ,
110
+ PlaceBase :: Local ( local) => self . builder . data . rev_lookup . locals [ local] ,
111
111
PlaceBase :: Promoted ( ..) |
112
- PlaceBase :: Static ( ..) => {
113
- Err ( MoveError :: cannot_move_out_of ( self . loc , Static ) )
114
- }
112
+ PlaceBase :: Static ( ..) =>
113
+ return Err ( MoveError :: cannot_move_out_of ( self . loc , Static ) ) ,
115
114
} ;
115
+
116
116
if !place. elems . is_empty ( ) {
117
+ let mir = self . builder . mir ;
118
+ let tcx = self . builder . tcx ;
119
+ let mut result_ty = place. base . ty ( mir) ;
117
120
for elem in place. elems . iter ( ) {
118
- result = self . move_path_for_projection ( place, place, elem) ;
121
+ result = self . move_path_for_projection ( place, result, result_ty, elem) ?;
122
+ result_ty = PlaceTy :: from ( result_ty) . projection_ty ( tcx, elem) . to_ty ( tcx) ;
119
123
}
120
124
}
121
- result
125
+
126
+ Ok ( result)
122
127
}
123
128
124
129
fn create_move_path ( & mut self , place : & Place < ' tcx > ) {
@@ -127,24 +132,23 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
127
132
let _ = self . move_path_for ( place) ;
128
133
}
129
134
130
- fn move_path_for_projection ( & mut self ,
131
- place : & Place < ' tcx > ,
132
- base_place : & Place < ' tcx > ,
133
- projection : & PlaceElem < ' tcx >
135
+ fn move_path_for_projection (
136
+ & mut self ,
137
+ place : & Place < ' tcx > ,
138
+ base : MovePathIndex ,
139
+ base_ty : Ty < ' tcx > ,
140
+ projection : & PlaceElem < ' tcx >
134
141
) -> Result < MovePathIndex , MoveError < ' tcx > > {
135
- let base = try!( self . move_path_for ( base_place) ) ;
136
- let mir = self . builder . mir ;
137
142
let tcx = self . builder . tcx ;
138
- let place_ty = base_place. ty ( mir, tcx) . to_ty ( tcx) ;
139
- match place_ty. sty {
143
+ match base_ty. sty {
140
144
ty:: TyRef ( ..) | ty:: TyRawPtr ( ..) =>
141
145
return Err ( MoveError :: cannot_move_out_of (
142
146
self . loc ,
143
147
BorrowedContent { target_place : place. clone ( ) } ) ) ,
144
148
ty:: TyAdt ( adt, _) if adt. has_dtor ( tcx) && !adt. is_box ( ) =>
145
149
return Err ( MoveError :: cannot_move_out_of ( self . loc ,
146
150
InteriorOfTypeWithDestructor {
147
- container_ty : place_ty
151
+ container_ty : base_ty
148
152
} ) ) ,
149
153
// move out of union - always move the entire union
150
154
ty:: TyAdt ( adt, _) if adt. is_union ( ) =>
@@ -153,7 +157,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
153
157
return Err ( MoveError :: cannot_move_out_of (
154
158
self . loc ,
155
159
InteriorOfSliceOrArray {
156
- ty : place_ty , is_index : match projection {
160
+ ty : base_ty , is_index : match projection {
157
161
ProjectionElem :: Index ( ..) => true ,
158
162
_ => false
159
163
} ,
@@ -163,7 +167,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
163
167
return Err ( MoveError :: cannot_move_out_of (
164
168
self . loc ,
165
169
InteriorOfSliceOrArray {
166
- ty : place_ty , is_index : true
170
+ ty : base_ty , is_index : true
167
171
} ) ) ,
168
172
_ => {
169
173
// FIXME: still badly broken
0 commit comments