@@ -95,82 +95,87 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
95
95
-> Result < MovePathIndex , MoveError < ' tcx > >
96
96
{
97
97
debug ! ( "lookup({:?})" , place) ;
98
- match * place {
99
- Place :: Base ( PlaceBase :: Local ( local) ) => Ok ( self . builder . data . rev_lookup . locals [ local] ) ,
100
- Place :: Base ( PlaceBase :: Static ( ..) ) => {
101
- Err ( MoveError :: cannot_move_out_of ( self . loc , Static ) )
102
- }
103
- Place :: Projection ( ref proj) => {
104
- self . move_path_for_projection ( place, proj)
98
+ place. iterate ( |place_base, place_projection| {
99
+ let mut base = match place_base {
100
+ PlaceBase :: Local ( local) => self . builder . data . rev_lookup . locals [ * local] ,
101
+ PlaceBase :: Static ( ..) => {
102
+ return Err ( MoveError :: cannot_move_out_of ( self . loc , Static ) ) ;
103
+ }
104
+ } ;
105
+
106
+ for proj in place_projection {
107
+ let mir = self . builder . mir ;
108
+ let tcx = self . builder . tcx ;
109
+ let place_ty = proj. base . ty ( mir, tcx) . ty ;
110
+ match place_ty. sty {
111
+ ty:: Ref ( ..) | ty:: RawPtr ( ..) =>
112
+ return Err ( MoveError :: cannot_move_out_of (
113
+ self . loc ,
114
+ BorrowedContent {
115
+ target_place : Place :: Projection ( Box :: new ( proj. clone ( ) ) ) ,
116
+ } ) ) ,
117
+ ty:: Adt ( adt, _) if adt. has_dtor ( tcx) && !adt. is_box ( ) =>
118
+ return Err ( MoveError :: cannot_move_out_of ( self . loc ,
119
+ InteriorOfTypeWithDestructor {
120
+ container_ty : place_ty
121
+ } ) ) ,
122
+ // move out of union - always move the entire union
123
+ ty:: Adt ( adt, _) if adt. is_union ( ) =>
124
+ return Err ( MoveError :: UnionMove { path : base } ) ,
125
+ ty:: Slice ( _) =>
126
+ return Err ( MoveError :: cannot_move_out_of (
127
+ self . loc ,
128
+ InteriorOfSliceOrArray {
129
+ ty : place_ty, is_index : match proj. elem {
130
+ ProjectionElem :: Index ( ..) => true ,
131
+ _ => false
132
+ } ,
133
+ } ) ) ,
134
+ ty:: Array ( ..) => match proj. elem {
135
+ ProjectionElem :: Index ( ..) =>
136
+ return Err ( MoveError :: cannot_move_out_of (
137
+ self . loc ,
138
+ InteriorOfSliceOrArray {
139
+ ty : place_ty, is_index : true
140
+ } ) ) ,
141
+ _ => {
142
+ // FIXME: still badly broken
143
+ }
144
+ } ,
145
+ _ => { }
146
+ } ;
147
+
148
+ base = match self
149
+ . builder
150
+ . data
151
+ . rev_lookup
152
+ . projections
153
+ . entry ( ( base, proj. elem . lift ( ) ) )
154
+ {
155
+ Entry :: Occupied ( ent) => * ent. get ( ) ,
156
+ Entry :: Vacant ( ent) => {
157
+ let path = MoveDataBuilder :: new_move_path (
158
+ & mut self . builder . data . move_paths ,
159
+ & mut self . builder . data . path_map ,
160
+ & mut self . builder . data . init_path_map ,
161
+ Some ( base) ,
162
+ Place :: Projection ( Box :: new ( proj. clone ( ) ) ) ,
163
+ ) ;
164
+ ent. insert ( path) ;
165
+ path
166
+ }
167
+ } ;
105
168
}
106
- }
169
+
170
+ Ok ( base)
171
+ } )
107
172
}
108
173
109
174
fn create_move_path ( & mut self , place : & Place < ' tcx > ) {
110
175
// This is an non-moving access (such as an overwrite or
111
176
// drop), so this not being a valid move path is OK.
112
177
let _ = self . move_path_for ( place) ;
113
178
}
114
-
115
- fn move_path_for_projection ( & mut self ,
116
- place : & Place < ' tcx > ,
117
- proj : & Projection < ' tcx > )
118
- -> Result < MovePathIndex , MoveError < ' tcx > >
119
- {
120
- let base = self . move_path_for ( & proj. base ) ?;
121
- let mir = self . builder . mir ;
122
- let tcx = self . builder . tcx ;
123
- let place_ty = proj. base . ty ( mir, tcx) . ty ;
124
- match place_ty. sty {
125
- ty:: Ref ( ..) | ty:: RawPtr ( ..) =>
126
- return Err ( MoveError :: cannot_move_out_of (
127
- self . loc ,
128
- BorrowedContent { target_place : place. clone ( ) } ) ) ,
129
- ty:: Adt ( adt, _) if adt. has_dtor ( tcx) && !adt. is_box ( ) =>
130
- return Err ( MoveError :: cannot_move_out_of ( self . loc ,
131
- InteriorOfTypeWithDestructor {
132
- container_ty : place_ty
133
- } ) ) ,
134
- // move out of union - always move the entire union
135
- ty:: Adt ( adt, _) if adt. is_union ( ) =>
136
- return Err ( MoveError :: UnionMove { path : base } ) ,
137
- ty:: Slice ( _) =>
138
- return Err ( MoveError :: cannot_move_out_of (
139
- self . loc ,
140
- InteriorOfSliceOrArray {
141
- ty : place_ty, is_index : match proj. elem {
142
- ProjectionElem :: Index ( ..) => true ,
143
- _ => false
144
- } ,
145
- } ) ) ,
146
- ty:: Array ( ..) => match proj. elem {
147
- ProjectionElem :: Index ( ..) =>
148
- return Err ( MoveError :: cannot_move_out_of (
149
- self . loc ,
150
- InteriorOfSliceOrArray {
151
- ty : place_ty, is_index : true
152
- } ) ) ,
153
- _ => {
154
- // FIXME: still badly broken
155
- }
156
- } ,
157
- _ => { }
158
- } ;
159
- match self . builder . data . rev_lookup . projections . entry ( ( base, proj. elem . lift ( ) ) ) {
160
- Entry :: Occupied ( ent) => Ok ( * ent. get ( ) ) ,
161
- Entry :: Vacant ( ent) => {
162
- let path = MoveDataBuilder :: new_move_path (
163
- & mut self . builder . data . move_paths ,
164
- & mut self . builder . data . path_map ,
165
- & mut self . builder . data . init_path_map ,
166
- Some ( base) ,
167
- place. clone ( )
168
- ) ;
169
- ent. insert ( path) ;
170
- Ok ( path)
171
- }
172
- }
173
- }
174
179
}
175
180
176
181
impl < ' a , ' gcx , ' tcx > MoveDataBuilder < ' a , ' gcx , ' tcx > {
0 commit comments