about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2017-09-03 21:55:41 +0300
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2017-09-03 21:55:41 +0300
commit2f42cd848905e4d473cacce0d9da769b2e712f0c (patch)
treece1bf0fcc9c822e2ef31a1a5d7e0e169b1d281a4
parentc9119252438a0f6c6c7a289bac91dd9600d45dd0 (diff)
downloadrust-2f42cd848905e4d473cacce0d9da769b2e712f0c.tar.gz
rust-2f42cd848905e4d473cacce0d9da769b2e712f0c.zip
rustc_mir: use Local in ProjectionElem::Index.
-rw-r--r--src/librustc/mir/mod.rs10
-rw-r--r--src/librustc/mir/visit.rs4
-rw-r--r--src/librustc/ty/structural_impls.rs2
-rw-r--r--src/librustc_mir/borrow_check.rs25
-rw-r--r--src/librustc_mir/build/expr/as_lvalue.rs9
-rw-r--r--src/librustc_mir/build/expr/as_operand.rs2
-rw-r--r--src/librustc_mir/build/expr/as_temp.rs16
-rw-r--r--src/librustc_mir/build/expr/into.rs2
-rw-r--r--src/librustc_mir/dataflow/move_paths/abs_domain.rs7
-rw-r--r--src/librustc_mir/shim.rs28
-rw-r--r--src/librustc_mir/transform/type_check.rs7
-rw-r--r--src/librustc_mir/util/elaborate_drops.rs21
-rw-r--r--src/librustc_trans/mir/constant.rs3
-rw-r--r--src/librustc_trans/mir/lvalue.rs3
14 files changed, 65 insertions, 74 deletions
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 1ea6c461fc1..4732f99c5c4 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1077,12 +1077,12 @@ pub enum ProjectionElem<'tcx, V, T> {
 }
 
 /// Alias for projections as they appear in lvalues, where the base is an lvalue
-/// and the index is an operand.
-pub type LvalueProjection<'tcx> = Projection<'tcx, Lvalue<'tcx>, Operand<'tcx>, Ty<'tcx>>;
+/// and the index is a local.
+pub type LvalueProjection<'tcx> = Projection<'tcx, Lvalue<'tcx>, Local, Ty<'tcx>>;
 
 /// Alias for projections as they appear in lvalues, where the base is an lvalue
-/// and the index is an operand.
-pub type LvalueElem<'tcx> = ProjectionElem<'tcx, Operand<'tcx>, Ty<'tcx>>;
+/// and the index is a local.
+pub type LvalueElem<'tcx> = ProjectionElem<'tcx, Local, Ty<'tcx>>;
 
 newtype_index!(Field, "field");
 
@@ -1099,7 +1099,7 @@ impl<'tcx> Lvalue<'tcx> {
         self.elem(ProjectionElem::Downcast(adt_def, variant_index))
     }
 
-    pub fn index(self, index: Operand<'tcx>) -> Lvalue<'tcx> {
+    pub fn index(self, index: Local) -> Lvalue<'tcx> {
         self.elem(ProjectionElem::Index(index))
     }
 
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index 6ee43953958..5394d42aeaa 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -664,8 +664,8 @@ macro_rules! make_mir_visitor {
                     ProjectionElem::Field(_field, ref $($mutability)* ty) => {
                         self.visit_ty(ty, Lookup::Loc(location));
                     }
-                    ProjectionElem::Index(ref $($mutability)* operand) => {
-                        self.visit_operand(operand, location);
+                    ProjectionElem::Index(ref $($mutability)* local) => {
+                        self.visit_local(local, LvalueContext::Consume, location);
                     }
                     ProjectionElem::ConstantIndex { offset: _,
                                                     min_length: _,
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index ae05568ab41..44b505e1965 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -421,7 +421,7 @@ macro_rules! CopyImpls {
     }
 }
 
-CopyImpls! { (), hir::Unsafety, abi::Abi, hir::def_id::DefId }
+CopyImpls! { (), hir::Unsafety, abi::Abi, hir::def_id::DefId, ::mir::Local }
 
 impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> (T, U) {
diff --git a/src/librustc_mir/borrow_check.rs b/src/librustc_mir/borrow_check.rs
index af550aea07e..edce75425a4 100644
--- a/src/librustc_mir/borrow_check.rs
+++ b/src/librustc_mir/borrow_check.rs
@@ -710,7 +710,7 @@ mod restrictions {
 
     use rustc::hir;
     use rustc::ty::{self, TyCtxt};
-    use rustc::mir::{Lvalue, Mir, Operand, ProjectionElem};
+    use rustc::mir::{Lvalue, Mir, ProjectionElem};
 
     pub(super) struct Restrictions<'c, 'tcx: 'c> {
         mir: &'c Mir<'tcx>,
@@ -809,12 +809,7 @@ mod restrictions {
                         ProjectionElem::Downcast(..) |
                         ProjectionElem::Subslice { .. } |
                         ProjectionElem::ConstantIndex { .. } |
-                        ProjectionElem::Index(Operand::Constant(..)) => {
-                            cursor = &proj.base;
-                            continue 'cursor;
-                        }
-                        ProjectionElem::Index(Operand::Consume(ref index)) => {
-                            self.lvalue_stack.push(index); // FIXME: did old borrowck do this?
+                        ProjectionElem::Index(_) => {
                             cursor = &proj.base;
                             continue 'cursor;
                         }
@@ -1004,7 +999,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
                         ("",   format!(""), None), // (dont emit downcast info)
                     ProjectionElem::Field(field, _ty) =>
                         ("",   format!(".{}", field.index()), None),
-                    ProjectionElem::Index(ref index) =>
+                    ProjectionElem::Index(index) =>
                         ("",   format!(""), Some(index)),
                     ProjectionElem::ConstantIndex { offset, min_length, from_end: true } =>
                         ("",   format!("[{} of {}]", offset, min_length), None),
@@ -1021,23 +1016,11 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
                 self.append_lvalue_to_string(&proj.base, buf);
                 if let Some(index) = index_operand {
                     buf.push_str("[");
-                    self.append_operand_to_string(index, buf);
+                    self.append_lvalue_to_string(&Lvalue::Local(index), buf);
                     buf.push_str("]");
                 } else {
                     buf.push_str(&suffix);
                 }
-
-            }
-        }
-    }
-
-    fn append_operand_to_string(&self, operand: &Operand, buf: &mut String) {
-        match *operand {
-            Operand::Consume(ref lvalue) => {
-                self.append_lvalue_to_string(lvalue, buf);
-            }
-            Operand::Constant(ref constant) => {
-                buf.push_str(&format!("{:?}", constant));
             }
         }
     }
diff --git a/src/librustc_mir/build/expr/as_lvalue.rs b/src/librustc_mir/build/expr/as_lvalue.rs
index 01b76af1576..9cbaff2c113 100644
--- a/src/librustc_mir/build/expr/as_lvalue.rs
+++ b/src/librustc_mir/build/expr/as_lvalue.rs
@@ -61,7 +61,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                 // region_scope=None so lvalue indexes live forever. They are scalars so they
                 // do not need storage annotations, and they are often copied between
                 // places.
-                let idx = unpack!(block = this.as_operand(block, None, index));
+                let idx = unpack!(block = this.as_temp(block, None, index));
 
                 // bounds check:
                 let (len, lt) = (this.temp(usize_ty.clone(), expr_span),
@@ -70,12 +70,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                                      &len, Rvalue::Len(slice.clone()));
                 this.cfg.push_assign(block, source_info, // lt = idx < len
                                      &lt, Rvalue::BinaryOp(BinOp::Lt,
-                                                           idx.clone(),
+                                                           Operand::Consume(Lvalue::Local(idx)),
                                                            Operand::Consume(len.clone())));
 
                 let msg = AssertMessage::BoundsCheck {
                     len: Operand::Consume(len),
-                    index: idx.clone()
+                    index: Operand::Consume(Lvalue::Local(idx))
                 };
                 let success = this.assert(block, Operand::Consume(lt), true,
                                           msg, expr_span);
@@ -127,7 +127,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                     Some(Category::Lvalue) => false,
                     _ => true,
                 });
-                this.as_temp(block, expr.temp_lifetime, expr)
+                let temp = unpack!(block = this.as_temp(block, expr.temp_lifetime, expr));
+                block.and(Lvalue::Local(temp))
             }
         }
     }
diff --git a/src/librustc_mir/build/expr/as_operand.rs b/src/librustc_mir/build/expr/as_operand.rs
index ea1b53add5e..0a72ce8d05e 100644
--- a/src/librustc_mir/build/expr/as_operand.rs
+++ b/src/librustc_mir/build/expr/as_operand.rs
@@ -74,7 +74,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             Category::Rvalue(..) => {
                 let operand =
                     unpack!(block = this.as_temp(block, scope, expr));
-                block.and(Operand::Consume(operand))
+                block.and(Operand::Consume(Lvalue::Local(operand)))
             }
         }
     }
diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs
index ed259867a48..675d43dd4b6 100644
--- a/src/librustc_mir/build/expr/as_temp.rs
+++ b/src/librustc_mir/build/expr/as_temp.rs
@@ -23,7 +23,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                       block: BasicBlock,
                       temp_lifetime: Option<region::Scope>,
                       expr: M)
-                      -> BlockAnd<Lvalue<'tcx>>
+                      -> BlockAnd<Local>
         where M: Mirror<'tcx, Output = Expr<'tcx>>
     {
         let expr = self.hir.mirror(expr);
@@ -34,7 +34,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                     mut block: BasicBlock,
                     temp_lifetime: Option<region::Scope>,
                     expr: Expr<'tcx>)
-                    -> BlockAnd<Lvalue<'tcx>> {
+                    -> BlockAnd<Local> {
         debug!("expr_as_temp(block={:?}, temp_lifetime={:?}, expr={:?})",
                block, temp_lifetime, expr);
         let this = self;
@@ -47,13 +47,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             });
         }
 
-        let expr_ty = expr.ty.clone();
-        let temp = this.temp(expr_ty.clone(), expr_span);
+        let expr_ty = expr.ty;
+        let temp = this.local_decls.push(LocalDecl::new_temp(expr_ty, expr_span));
 
         if !expr_ty.is_never() {
             this.cfg.push(block, Statement {
                 source_info,
-                kind: StatementKind::StorageLive(temp.clone())
+                kind: StatementKind::StorageLive(Lvalue::Local(temp))
             });
         }
 
@@ -68,10 +68,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             Category::Lvalue => {
                 let lvalue = unpack!(block = this.as_lvalue(block, expr));
                 let rvalue = Rvalue::Use(Operand::Consume(lvalue));
-                this.cfg.push_assign(block, source_info, &temp, rvalue);
+                this.cfg.push_assign(block, source_info, &Lvalue::Local(temp), rvalue);
             }
             _ => {
-                unpack!(block = this.into(&temp, block, expr));
+                unpack!(block = this.into(&Lvalue::Local(temp), block, expr));
             }
         }
 
@@ -79,7 +79,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
         // anything because no values with a destructor can be created in
         // a constant at this time, even if the type may need dropping.
         if let Some(temp_lifetime) = temp_lifetime {
-            this.schedule_drop(expr_span, temp_lifetime, &temp, expr_ty);
+            this.schedule_drop(expr_span, temp_lifetime, &Lvalue::Local(temp), expr_ty);
         }
 
         block.and(temp)
diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs
index 6d7c2132665..80a126dc425 100644
--- a/src/librustc_mir/build/expr/into.rs
+++ b/src/librustc_mir/build/expr/into.rs
@@ -229,7 +229,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
 
                     let topmost_scope = this.topmost_scope();
                     let ptr = unpack!(block = this.as_temp(block, Some(topmost_scope), ptr));
-                    this.into(&ptr.deref(), block, val)
+                    this.into(&Lvalue::Local(ptr).deref(), block, val)
                 } else {
                     let args: Vec<_> =
                         args.into_iter()
diff --git a/src/librustc_mir/dataflow/move_paths/abs_domain.rs b/src/librustc_mir/dataflow/move_paths/abs_domain.rs
index 173396f2245..00825c7a880 100644
--- a/src/librustc_mir/dataflow/move_paths/abs_domain.rs
+++ b/src/librustc_mir/dataflow/move_paths/abs_domain.rs
@@ -21,8 +21,7 @@
 //! `a[x]` would still overlap them both. But that is not this
 //! representation does today.)
 
-use rustc::mir::LvalueElem;
-use rustc::mir::{Operand, ProjectionElem};
+use rustc::mir::{Local, LvalueElem, Operand, ProjectionElem};
 use rustc::ty::Ty;
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
@@ -40,6 +39,10 @@ impl<'tcx> Lift for Operand<'tcx> {
     type Abstract = AbstractOperand;
     fn lift(&self) -> Self::Abstract { AbstractOperand }
 }
+impl Lift for Local {
+    type Abstract = AbstractOperand;
+    fn lift(&self) -> Self::Abstract { AbstractOperand }
+}
 impl<'tcx> Lift for Ty<'tcx> {
     type Abstract = AbstractType;
     fn lift(&self) -> Self::Abstract { AbstractType }
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 1e0858d6864..d3c886dab4e 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -479,9 +479,10 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
 
     fn array_shim(&mut self, ty: ty::Ty<'tcx>, len: usize) {
         let tcx = self.tcx;
+        let span = self.span;
         let rcvr = Lvalue::Local(Local::new(1+0)).deref();
 
-        let beg = self.make_lvalue(Mutability::Mut, tcx.types.usize);
+        let beg = self.local_decls.push(temp_decl(Mutability::Mut, tcx.types.usize, span));
         let end = self.make_lvalue(Mutability::Not, tcx.types.usize);
         let ret = self.make_lvalue(Mutability::Mut, tcx.mk_array(ty, len));
 
@@ -492,7 +493,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
         let inits = vec![
             self.make_statement(
                 StatementKind::Assign(
-                    beg.clone(),
+                    Lvalue::Local(beg),
                     Rvalue::Use(Operand::Constant(self.make_usize(0)))
                 )
             ),
@@ -510,19 +511,19 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
         //     BB #3;
         // }
         // BB #4;
-        self.loop_header(beg.clone(), end, BasicBlock::new(2), BasicBlock::new(4), false);
+        self.loop_header(Lvalue::Local(beg), end, BasicBlock::new(2), BasicBlock::new(4), false);
 
         // BB #2
         // `let cloned = Clone::clone(rcvr[beg])`;
         // Goto #3 if ok, #5 if unwinding happens.
-        let rcvr_field = rcvr.clone().index(Operand::Consume(beg.clone()));
+        let rcvr_field = rcvr.clone().index(beg);
         let cloned = self.make_clone_call(ty, rcvr_field, BasicBlock::new(3), BasicBlock::new(5));
 
         // BB #3
         // `ret[beg] = cloned;`
         // `beg = beg + 1;`
         // `goto #1`;
-        let ret_field = ret.clone().index(Operand::Consume(beg.clone()));
+        let ret_field = ret.clone().index(beg);
         let statements = vec![
             self.make_statement(
                 StatementKind::Assign(
@@ -532,10 +533,10 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
             ),
             self.make_statement(
                 StatementKind::Assign(
-                    beg.clone(),
+                    Lvalue::Local(beg),
                     Rvalue::BinaryOp(
                         BinOp::Add,
-                        Operand::Consume(beg.clone()),
+                        Operand::Consume(Lvalue::Local(beg)),
                         Operand::Constant(self.make_usize(1))
                     )
                 )
@@ -558,10 +559,10 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
         // `let mut beg = 0;`
         // goto #6;
         let end = beg;
-        let beg = self.make_lvalue(Mutability::Mut, tcx.types.usize);
+        let beg = self.local_decls.push(temp_decl(Mutability::Mut, tcx.types.usize, span));
         let init = self.make_statement(
             StatementKind::Assign(
-                beg.clone(),
+                Lvalue::Local(beg),
                 Rvalue::Use(Operand::Constant(self.make_usize(0)))
             )
         );
@@ -572,12 +573,13 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
         //     BB #8;
         // }
         // BB #9;
-        self.loop_header(beg.clone(), end, BasicBlock::new(7), BasicBlock::new(9), true);
+        self.loop_header(Lvalue::Local(beg), Lvalue::Local(end),
+                         BasicBlock::new(7), BasicBlock::new(9), true);
 
         // BB #7 (cleanup)
         // `drop(ret[beg])`;
         self.block(vec![], TerminatorKind::Drop {
-            location: ret.index(Operand::Consume(beg.clone())),
+            location: ret.index(beg),
             target: BasicBlock::new(8),
             unwind: None,
         }, true);
@@ -587,10 +589,10 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
         // `goto #6;`
         let statement = self.make_statement(
             StatementKind::Assign(
-                beg.clone(),
+                Lvalue::Local(beg),
                 Rvalue::BinaryOp(
                     BinOp::Add,
-                    Operand::Consume(beg.clone()),
+                    Operand::Consume(Lvalue::Local(beg)),
                     Operand::Constant(self.make_usize(1))
                 )
             )
diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs
index 59cf5903aa9..ac610ca163b 100644
--- a/src/librustc_mir/transform/type_check.rs
+++ b/src/librustc_mir/transform/type_check.rs
@@ -165,7 +165,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
                            base: LvalueTy<'tcx>,
                            pi: &LvalueElem<'tcx>,
                            lvalue: &Lvalue<'tcx>,
-                           location: Location)
+                           _: Location)
                            -> LvalueTy<'tcx> {
         debug!("sanitize_projection: {:?} {:?} {:?}", base, pi, lvalue);
         let tcx = self.tcx();
@@ -181,9 +181,8 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
                     })
                 }
             }
-            ProjectionElem::Index(ref i) => {
-                self.visit_operand(i, location);
-                let index_ty = i.ty(self.mir, tcx);
+            ProjectionElem::Index(i) => {
+                let index_ty = Lvalue::Local(i).ty(self.mir, tcx).to_ty(tcx);
                 if index_ty != tcx.types.usize {
                     LvalueTy::Ty {
                         ty: span_mirbug_and_err!(self, i, "index by non-usize {:?}", i)
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index 41618960337..f3b121f2eed 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -565,7 +565,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
     ///    drop(ptr)
     fn drop_loop(&mut self,
                  succ: BasicBlock,
-                 cur: &Lvalue<'tcx>,
+                 cur: Local,
                  length_or_end: &Lvalue<'tcx>,
                  ety: Ty<'tcx>,
                  unwind: Unwind,
@@ -584,20 +584,20 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
 
         let one = self.constant_usize(1);
         let (ptr_next, cur_next) = if ptr_based {
-            (Rvalue::Use(use_(cur)),
-             Rvalue::BinaryOp(BinOp::Offset, use_(cur), one))
+            (Rvalue::Use(use_(&Lvalue::Local(cur))),
+             Rvalue::BinaryOp(BinOp::Offset, use_(&Lvalue::Local(cur)), one))
         } else {
             (Rvalue::Ref(
                  tcx.types.re_erased,
                  BorrowKind::Mut,
-                 self.lvalue.clone().index(use_(cur))),
-             Rvalue::BinaryOp(BinOp::Add, use_(cur), one))
+                 self.lvalue.clone().index(cur)),
+             Rvalue::BinaryOp(BinOp::Add, use_(&Lvalue::Local(cur)), one))
         };
 
         let drop_block = BasicBlockData {
             statements: vec![
                 self.assign(ptr, ptr_next),
-                self.assign(cur, cur_next)
+                self.assign(&Lvalue::Local(cur), cur_next)
             ],
             is_cleanup: unwind.is_cleanup(),
             terminator: Some(Terminator {
@@ -611,7 +611,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
         let loop_block = BasicBlockData {
             statements: vec![
                 self.assign(can_go, Rvalue::BinaryOp(BinOp::Eq,
-                                                     use_(cur),
+                                                     use_(&Lvalue::Local(cur)),
                                                      use_(length_or_end)))
             ],
             is_cleanup: unwind.is_cleanup(),
@@ -678,7 +678,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
             tcx.types.usize
         };
 
-        let cur = Lvalue::Local(self.new_temp(iter_ty));
+        let cur = self.new_temp(iter_ty);
         let length = Lvalue::Local(self.new_temp(tcx.types.usize));
         let length_or_end = if ptr_based {
             Lvalue::Local(self.new_temp(iter_ty))
@@ -688,7 +688,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
 
         let unwind = self.unwind.map(|unwind| {
             self.drop_loop(unwind,
-                           &cur,
+                           cur,
                            &length_or_end,
                            ety,
                            Unwind::InCleanup,
@@ -698,12 +698,13 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
         let succ = self.succ; // FIXME(#6393)
         let loop_block = self.drop_loop(
             succ,
-            &cur,
+            cur,
             &length_or_end,
             ety,
             unwind,
             ptr_based);
 
+        let cur = Lvalue::Local(cur);
         let zero = self.constant_usize(0);
         let mut drop_block_stmts = vec![];
         drop_block_stmts.push(self.assign(&length, Rvalue::Len(self.lvalue.clone())));
diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs
index 65b9fec7eff..9987c9c3310 100644
--- a/src/librustc_trans/mir/constant.rs
+++ b/src/librustc_trans/mir/constant.rs
@@ -471,7 +471,8 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
                         };
                         (Base::Value(llprojected), llextra)
                     }
-                    mir::ProjectionElem::Index(ref index) => {
+                    mir::ProjectionElem::Index(index) => {
+                        let index = &mir::Operand::Consume(mir::Lvalue::Local(index));
                         let llindex = self.const_operand(index, span)?.llval;
 
                         let iv = if let Some(iv) = common::const_to_opt_u128(llindex, false) {
diff --git a/src/librustc_trans/mir/lvalue.rs b/src/librustc_trans/mir/lvalue.rs
index 89c76ccdd27..8155303b0d3 100644
--- a/src/librustc_trans/mir/lvalue.rs
+++ b/src/librustc_trans/mir/lvalue.rs
@@ -333,7 +333,8 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
                         };
                         (tr_base.trans_field_ptr(bcx, field.index()), llextra)
                     }
-                    mir::ProjectionElem::Index(ref index) => {
+                    mir::ProjectionElem::Index(index) => {
+                        let index = &mir::Operand::Consume(mir::Lvalue::Local(index));
                         let index = self.trans_operand(bcx, index);
                         let llindex = self.prepare_index(bcx, index.immediate());
                         ((tr_base.project_index(bcx, llindex), align), ptr::null_mut())