]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_borrowck/borrowck/gather_loans/mod.rs
Auto merge of #43710 - zackmdavis:field_init_shorthand_power_slam, r=Mark-Simulacrum
[rust.git] / src / librustc_borrowck / borrowck / gather_loans / mod.rs
index 85a09969ac81c68cd950cd15ac9de31566b3bd11..4ff603b7eae01441e9f26a0e646b92a72c6aa12a 100644 (file)
@@ -18,7 +18,6 @@
 
 use borrowck::*;
 use borrowck::move_data::MoveData;
-use rustc::infer::InferCtxt;
 use rustc::middle::expr_use_visitor as euv;
 use rustc::middle::mem_categorization as mc;
 use rustc::middle::mem_categorization::Categorization;
@@ -40,11 +39,9 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
                                     body: hir::BodyId)
                                     -> (Vec<Loan<'tcx>>, move_data::MoveData<'tcx>) {
     let def_id = bccx.tcx.hir.body_owner_def_id(body);
-    let infcx = bccx.tcx.borrowck_fake_infer_ctxt(body);
     let param_env = bccx.tcx.param_env(def_id);
     let mut glcx = GatherLoanCtxt {
-        bccx: bccx,
-        infcx: &infcx,
+        bccx,
         all_loans: Vec::new(),
         item_ub: region::CodeExtent::Misc(body.node_id),
         move_data: MoveData::new(),
@@ -52,7 +49,8 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
     };
 
     let body = glcx.bccx.tcx.hir.body(body);
-    euv::ExprUseVisitor::new(&mut glcx, &bccx.region_maps, &infcx, param_env).consume_body(body);
+    euv::ExprUseVisitor::new(&mut glcx, bccx.tcx, param_env, &bccx.region_maps, bccx.tables)
+        .consume_body(body);
 
     glcx.report_potential_errors();
     let GatherLoanCtxt { all_loans, move_data, .. } = glcx;
@@ -61,7 +59,6 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
 
 struct GatherLoanCtxt<'a, 'tcx: 'a> {
     bccx: &'a BorrowckCtxt<'a, 'tcx>,
-    infcx: &'a InferCtxt<'a, 'tcx, 'tcx>,
     move_data: move_data::MoveData<'tcx>,
     move_error_collector: move_error::MoveErrorCollector<'tcx>,
     all_loans: Vec<Loan<'tcx>>,
@@ -158,7 +155,9 @@ fn mutate(&mut self,
     }
 
     fn decl_without_init(&mut self, id: ast::NodeId, _span: Span) {
-        let ty = self.infcx.tables.borrow().node_id_to_type(id);
+        let ty = self.bccx
+                     .tables
+                     .node_id_to_type(self.bccx.tcx.hir.node_to_hir_id(id));
         gather_moves::gather_decl(self.bccx, &self.move_data, id, ty);
     }
 }
@@ -231,8 +230,8 @@ fn check_mutability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
             // Only mutable data can be lent as mutable.
             if !cmt.mutbl.is_mutable() {
                 Err(bccx.report(BckError { span: borrow_span,
-                                           cause: cause,
-                                           cmt: cmt,
+                                           cause,
+                                           cmt,
                                            code: err_mutbl }))
             } else {
                 Ok(())
@@ -390,13 +389,13 @@ fn guarantee_valid(&mut self,
 
                 Loan {
                     index: self.all_loans.len(),
-                    loan_path: loan_path,
+                    loan_path,
                     kind: req_kind,
-                    gen_scope: gen_scope,
-                    kill_scope: kill_scope,
+                    gen_scope,
+                    kill_scope,
                     span: borrow_span,
-                    restricted_paths: restricted_paths,
-                    cause: cause,
+                    restricted_paths,
+                    cause,
                 }
             }
         };
@@ -424,13 +423,13 @@ fn guarantee_valid(&mut self,
             //    let all_loans = &mut *self.all_loans; // FIXME(#5074)
             //    Loan {
             //        index: all_loans.len(),
-            //        loan_path: loan_path,
-            //        cmt: cmt,
+            //        loan_path,
+            //        cmt,
             //        mutbl: ConstMutability,
             //        gen_scope: borrow_id,
-            //        kill_scope: kill_scope,
+            //        kill_scope,
             //        span: borrow_span,
-            //        restrictions: restrictions
+            //        restrictions,
             //    }
         // }
     }
@@ -439,20 +438,41 @@ pub fn mark_loan_path_as_mutated(&self, loan_path: &LoanPath) {
         //! For mutable loans of content whose mutability derives
         //! from a local variable, mark the mutability decl as necessary.
 
-        match loan_path.kind {
-            LpVar(local_id) |
-            LpUpvar(ty::UpvarId{ var_id: local_id, closure_expr_id: _ }) => {
-                self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
-            }
-            LpDowncast(ref base, _) |
-            LpExtend(ref base, mc::McInherited, _) |
-            LpExtend(ref base, mc::McDeclared, _) => {
-                self.mark_loan_path_as_mutated(&base);
-            }
-            LpExtend(_, mc::McImmutable, _) => {
-                // Nothing to do.
+        let mut wrapped_path = Some(loan_path);
+        let mut through_borrow = false;
+
+        while let Some(current_path) = wrapped_path {
+            wrapped_path = match current_path.kind {
+                LpVar(local_id) => {
+                    if !through_borrow {
+                        self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
+                    }
+                    None
+                }
+                LpUpvar(ty::UpvarId{ var_id, closure_expr_id: _ }) => {
+                    let local_id = self.tcx().hir.def_index_to_node_id(var_id);
+                    self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
+                    None
+                }
+                LpExtend(ref base, mc::McInherited, LpDeref(pointer_kind)) |
+                LpExtend(ref base, mc::McDeclared, LpDeref(pointer_kind)) => {
+                    if pointer_kind != mc::Unique {
+                        through_borrow = true;
+                    }
+                    Some(base)
+                }
+                LpDowncast(ref base, _) |
+                LpExtend(ref base, mc::McInherited, _) |
+                LpExtend(ref base, mc::McDeclared, _) => {
+                    Some(base)
+                }
+                LpExtend(_, mc::McImmutable, _) => {
+                    // Nothing to do.
+                    None
+                }
             }
         }
+
     }
 
     pub fn compute_gen_scope(&self,