Skip to content

Commit 2cd7680

Browse files
committed
rewrite builder so that it terminates
The idea is to update the `result` (and `result_ty` as we go)
1 parent 36b5cac commit 2cd7680

File tree

1 file changed

+23
-19
lines changed

1 file changed

+23
-19
lines changed

src/librustc_mir/dataflow/move_paths/builder.rs

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use rustc::ty::{self, TyCtxt};
11+
use rustc::ty::{self, Ty, TyCtxt};
1212
use rustc::mir::*;
13-
use rustc::mir::tcx::RvalueInitializationState;
13+
use rustc::mir::tcx::{PlaceTy, RvalueInitializationState};
1414
use rustc::util::nodemap::FxHashMap;
1515
use rustc_data_structures::indexed_vec::{IndexVec};
1616

@@ -107,18 +107,23 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
107107
{
108108
debug!("lookup({:?})", place);
109109
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],
111111
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)),
115114
};
115+
116116
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);
117120
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);
119123
}
120124
}
121-
result
125+
126+
Ok(result)
122127
}
123128

124129
fn create_move_path(&mut self, place: &Place<'tcx>) {
@@ -127,24 +132,23 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
127132
let _ = self.move_path_for(place);
128133
}
129134

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>
134141
) -> Result<MovePathIndex, MoveError<'tcx>> {
135-
let base = try!(self.move_path_for(base_place));
136-
let mir = self.builder.mir;
137142
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 {
140144
ty::TyRef(..) | ty::TyRawPtr(..) =>
141145
return Err(MoveError::cannot_move_out_of(
142146
self.loc,
143147
BorrowedContent { target_place: place.clone() })),
144148
ty::TyAdt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() =>
145149
return Err(MoveError::cannot_move_out_of(self.loc,
146150
InteriorOfTypeWithDestructor {
147-
container_ty: place_ty
151+
container_ty: base_ty
148152
})),
149153
// move out of union - always move the entire union
150154
ty::TyAdt(adt, _) if adt.is_union() =>
@@ -153,7 +157,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
153157
return Err(MoveError::cannot_move_out_of(
154158
self.loc,
155159
InteriorOfSliceOrArray {
156-
ty: place_ty, is_index: match projection {
160+
ty: base_ty, is_index: match projection {
157161
ProjectionElem::Index(..) => true,
158162
_ => false
159163
},
@@ -163,7 +167,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
163167
return Err(MoveError::cannot_move_out_of(
164168
self.loc,
165169
InteriorOfSliceOrArray {
166-
ty: place_ty, is_index: true
170+
ty: base_ty, is_index: true
167171
})),
168172
_ => {
169173
// FIXME: still badly broken

0 commit comments

Comments
 (0)