]> git.lizzy.rs Git - rust.git/commitdiff
erase regions in MIR borrowck when checking if type moves by default
authorNiko Matsakis <niko@alum.mit.edu>
Mon, 6 Nov 2017 16:52:39 +0000 (11:52 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Thu, 16 Nov 2017 10:57:46 +0000 (05:57 -0500)
src/librustc_mir/borrow_check.rs

index 93fd3e7637f8a685129ecee61d520ecd93213baf..70f4e41a9cbfe9a12cb07daf9cd6aefe889c10c7 100644 (file)
@@ -136,7 +136,6 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
         node_id: id,
         move_data: &mdpe.move_data,
         param_env: param_env,
-        fake_infer_ctxt: &infcx,
     };
 
     let mut state = InProgress::new(flow_borrows,
@@ -154,7 +153,6 @@ pub struct MirBorrowckCtxt<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
     node_id: ast::NodeId,
     move_data: &'cx MoveData<'tcx>,
     param_env: ParamEnv<'gcx>,
-    fake_infer_ctxt: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
 }
 
 // (forced to be `pub` due to its use as an associated type below.)
@@ -592,9 +590,20 @@ fn consume_lvalue(&mut self,
                       lvalue_span: (&Lvalue<'tcx>, Span),
                       flow_state: &InProgress<'cx, 'gcx, 'tcx>) {
         let lvalue = lvalue_span.0;
+
         let ty = lvalue.ty(self.mir, self.tcx).to_ty(self.tcx);
-        let moves_by_default =
-            self.fake_infer_ctxt.type_moves_by_default(self.param_env, ty, DUMMY_SP);
+
+        // Erase the regions in type before checking whether it moves by
+        // default. There are a few reasons to do this:
+        //
+        // - They should not affect the result.
+        // - It avoids adding new region constraints into the surrounding context,
+        //   which would trigger an ICE, since the infcx will have been "frozen" by
+        //   the NLL region context.
+        let gcx = self.tcx.global_tcx();
+        let erased_ty = gcx.lift(&self.tcx.erase_regions(&ty)).unwrap();
+        let moves_by_default = erased_ty.moves_by_default(gcx, self.param_env, DUMMY_SP);
+
         if moves_by_default {
             // move of lvalue: check if this is move of already borrowed path
             self.access_lvalue(context, lvalue_span, (Deep, Write(WriteKind::Move)), flow_state);