From 7cf142f78b82b0b2ae08b52ccb6a6e15c0270c38 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote <nnethercote@mozilla.com> Date: Wed, 2 May 2018 10:28:37 +1000 Subject: [PATCH] Avoid many `cmt` allocations. `cmt` is a ref-counted wrapper around `cmt_` The use of refcounting keeps `cmt` handling simple, but a lot of `cmt` instances are very short-lived, and heap-allocating the short-lived ones takes up time. This patch changes things in the following ways. - Most of the functions that produced `cmt` instances now produce `cmt_` instances. The `Rc::new` calls that occurred within those functions now occur at their call sites (but only when necessary, which isn't that often). - Many of the functions that took `cmt` arguments now take `&cmt_` arguments. This includes all the methods in the `Delegate` trait. As a result, the vast majority of the heap allocations are avoided. In an extreme case, the number of calls to malloc in tuple-stress drops from 9.9M to 7.9M, a drop of 20%. And the compile times for many runs of coercions, deep-vector, and tuple-stress drop by 1--2%. --- src/librustc/middle/expr_use_visitor.rs | 60 +++++----- src/librustc/middle/mem_categorization.rs | 105 +++++++++--------- src/librustc_borrowck/borrowck/check_loans.rs | 30 ++--- .../borrowck/gather_loans/gather_moves.rs | 29 +++-- .../borrowck/gather_loans/lifetime.rs | 15 ++- .../borrowck/gather_loans/mod.rs | 34 +++--- .../borrowck/gather_loans/restrictions.rs | 16 +-- src/librustc_borrowck/borrowck/mod.rs | 26 ++--- src/librustc_mir/hair/pattern/check_match.rs | 12 +- src/librustc_passes/rvalue_promotion.rs | 12 +- src/librustc_typeck/check/regionck.rs | 47 ++++---- src/librustc_typeck/check/upvar.rs | 31 +++--- 12 files changed, 208 insertions(+), 209 deletions(-) diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 2cc5a4a8fe639..725fcf1e6463b 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -28,6 +28,7 @@ use ty::{self, TyCtxt, adjustment}; use hir::{self, PatKind}; use rustc_data_structures::sync::Lrc; +use std::rc::Rc; use syntax::ast; use syntax::ptr::P; use syntax_pos::Span; @@ -44,7 +45,7 @@ pub trait Delegate<'tcx> { fn consume(&mut self, consume_id: ast::NodeId, consume_span: Span, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, mode: ConsumeMode); // The value found at `cmt` has been determined to match the @@ -61,14 +62,14 @@ pub trait Delegate<'tcx> { // called on a subpart of an input passed to `matched_pat). fn matched_pat(&mut self, matched_pat: &hir::Pat, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, mode: MatchMode); // The value found at `cmt` is either copied or moved via the // pattern binding `consume_pat`, depending on mode. fn consume_pat(&mut self, consume_pat: &hir::Pat, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, mode: ConsumeMode); // The value found at `borrow` is being borrowed at the point @@ -76,7 +77,7 @@ pub trait Delegate<'tcx> { fn borrow(&mut self, borrow_id: ast::NodeId, borrow_span: Span, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, loan_region: ty::Region<'tcx>, bk: ty::BorrowKind, loan_cause: LoanCause); @@ -90,7 +91,7 @@ pub trait Delegate<'tcx> { fn mutate(&mut self, assignment_id: ast::NodeId, assignment_span: Span, - assignee_cmt: mc::cmt<'tcx>, + assignee_cmt: &mc::cmt_<'tcx>, mode: MutateMode); } @@ -316,11 +317,11 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { let fn_body_scope_r = self.tcx().mk_region(ty::ReScope(region::Scope::Node(body.value.hir_id.local_id))); - let arg_cmt = self.mc.cat_rvalue( + let arg_cmt = Rc::new(self.mc.cat_rvalue( arg.id, arg.pat.span, fn_body_scope_r, // Args live only as long as the fn body. - arg_ty); + arg_ty)); self.walk_irrefutable_pat(arg_cmt, &arg.pat); } @@ -335,11 +336,11 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { fn delegate_consume(&mut self, consume_id: ast::NodeId, consume_span: Span, - cmt: mc::cmt<'tcx>) { + cmt: &mc::cmt_<'tcx>) { debug!("delegate_consume(consume_id={}, cmt={:?})", consume_id, cmt); - let mode = copy_or_move(&self.mc, self.param_env, &cmt, DirectRefMove); + let mode = copy_or_move(&self.mc, self.param_env, cmt, DirectRefMove); self.delegate.consume(consume_id, consume_span, cmt, mode); } @@ -353,7 +354,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { debug!("consume_expr(expr={:?})", expr); let cmt = return_if_err!(self.mc.cat_expr(expr)); - self.delegate_consume(expr.id, expr.span, cmt); + self.delegate_consume(expr.id, expr.span, &cmt); self.walk_expr(expr); } @@ -362,7 +363,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { expr: &hir::Expr, mode: MutateMode) { let cmt = return_if_err!(self.mc.cat_expr(expr)); - self.delegate.mutate(assignment_expr.id, assignment_expr.span, cmt, mode); + self.delegate.mutate(assignment_expr.id, assignment_expr.span, &cmt, mode); self.walk_expr(expr); } @@ -375,7 +376,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { expr, r, bk); let cmt = return_if_err!(self.mc.cat_expr(expr)); - self.delegate.borrow(expr.id, expr.span, cmt, r, bk, cause); + self.delegate.borrow(expr.id, expr.span, &cmt, r, bk, cause); self.walk_expr(expr) } @@ -435,7 +436,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { } hir::ExprMatch(ref discr, ref arms, _) => { - let discr_cmt = return_if_err!(self.mc.cat_expr(&discr)); + let discr_cmt = Rc::new(return_if_err!(self.mc.cat_expr(&discr))); let r = self.tcx().types.re_empty; self.borrow_expr(&discr, r, ty::ImmBorrow, MatchDiscriminant); @@ -619,7 +620,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { // "assigns", which is handled by // `walk_pat`: self.walk_expr(&expr); - let init_cmt = return_if_err!(self.mc.cat_expr(&expr)); + let init_cmt = Rc::new(return_if_err!(self.mc.cat_expr(&expr))); self.walk_irrefutable_pat(init_cmt, &local.pat); } } @@ -652,7 +653,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { None => { return; } }; - let with_cmt = return_if_err!(self.mc.cat_expr(&with_expr)); + let with_cmt = Rc::new(return_if_err!(self.mc.cat_expr(&with_expr))); // Select just those fields of the `with` // expression that will actually be used @@ -671,7 +672,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { with_field.name, with_field.ty(self.tcx(), substs) ); - self.delegate_consume(with_expr.id, with_expr.span, cmt_field); + self.delegate_consume(with_expr.id, with_expr.span, &cmt_field); } } } @@ -710,7 +711,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { adjustment::Adjust::Unsize => { // Creating a closure/fn-pointer or unsizing consumes // the input and stores it into the resulting rvalue. - self.delegate_consume(expr.id, expr.span, cmt.clone()); + self.delegate_consume(expr.id, expr.span, &cmt); } adjustment::Adjust::Deref(None) => {} @@ -722,12 +723,11 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { // this is an autoref of `x`. adjustment::Adjust::Deref(Some(ref deref)) => { let bk = ty::BorrowKind::from_mutbl(deref.mutbl); - self.delegate.borrow(expr.id, expr.span, cmt.clone(), - deref.region, bk, AutoRef); + self.delegate.borrow(expr.id, expr.span, &cmt, deref.region, bk, AutoRef); } adjustment::Adjust::Borrow(ref autoref) => { - self.walk_autoref(expr, cmt.clone(), autoref); + self.walk_autoref(expr, &cmt, autoref); } } cmt = return_if_err!(self.mc.cat_expr_adjusted(expr, cmt, &adjustment)); @@ -739,7 +739,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { /// after all relevant autoderefs have occurred. fn walk_autoref(&mut self, expr: &hir::Expr, - cmt_base: mc::cmt<'tcx>, + cmt_base: &mc::cmt_<'tcx>, autoref: &adjustment::AutoBorrow<'tcx>) { debug!("walk_autoref(expr.id={} cmt_base={:?} autoref={:?})", expr.id, @@ -852,7 +852,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { // Each match binding is effectively an assignment to the // binding being produced. let def = Def::Local(canonical_id); - if let Ok(binding_cmt) = mc.cat_def(pat.id, pat.span, pat_ty, def) { + if let Ok(ref binding_cmt) = mc.cat_def(pat.id, pat.span, pat_ty, def) { delegate.mutate(pat.id, pat.span, binding_cmt, MutateMode::Init); } @@ -861,13 +861,13 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { ty::BindByReference(m) => { if let ty::TyRef(r, _) = pat_ty.sty { let bk = ty::BorrowKind::from_mutbl(m); - delegate.borrow(pat.id, pat.span, cmt_pat, r, bk, RefBinding); + delegate.borrow(pat.id, pat.span, &cmt_pat, r, bk, RefBinding); } } ty::BindByValue(..) => { let mode = copy_or_move(mc, param_env, &cmt_pat, PatBindingMove); debug!("walk_pat binding consuming pat"); - delegate.consume_pat(pat, cmt_pat, mode); + delegate.consume_pat(pat, &cmt_pat, mode); } } } @@ -891,12 +891,12 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { let downcast_cmt = mc.cat_downcast_if_needed(pat, cmt_pat, variant_did); debug!("variant downcast_cmt={:?} pat={:?}", downcast_cmt, pat); - delegate.matched_pat(pat, downcast_cmt, match_mode); + delegate.matched_pat(pat, &downcast_cmt, match_mode); } Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) | Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => { debug!("struct cmt_pat={:?} pat={:?}", cmt_pat, pat); - delegate.matched_pat(pat, cmt_pat, match_mode); + delegate.matched_pat(pat, &cmt_pat, match_mode); } _ => {} } @@ -924,12 +924,12 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { self.param_env, &cmt_var, CaptureMove); - self.delegate.consume(closure_expr.id, freevar.span, cmt_var, mode); + self.delegate.consume(closure_expr.id, freevar.span, &cmt_var, mode); } ty::UpvarCapture::ByRef(upvar_borrow) => { self.delegate.borrow(closure_expr.id, fn_decl_span, - cmt_var, + &cmt_var, upvar_borrow.region, upvar_borrow.kind, ClosureCapture(freevar.span)); @@ -943,7 +943,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { closure_id: ast::NodeId, closure_span: Span, upvar: &hir::Freevar) - -> mc::McResult<mc::cmt<'tcx>> { + -> mc::McResult<mc::cmt_<'tcx>> { // Create the cmt for the variable being borrowed, from the // caller's perspective let var_hir_id = self.tcx().hir.node_to_hir_id(upvar.var_id()); @@ -954,7 +954,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { fn copy_or_move<'a, 'gcx, 'tcx>(mc: &mc::MemCategorizationContext<'a, 'gcx, 'tcx>, param_env: ty::ParamEnv<'tcx>, - cmt: &mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, move_reason: MoveReason) -> ConsumeMode { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 6f41f07dce8a7..f40a41cd29924 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -572,13 +572,13 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { Ok(ret_ty) } - pub fn cat_expr(&self, expr: &hir::Expr) -> McResult<cmt<'tcx>> { + pub fn cat_expr(&self, expr: &hir::Expr) -> McResult<cmt_<'tcx>> { // This recursion helper avoids going through *too many* // adjustments, since *only* non-overloaded deref recurses. fn helper<'a, 'gcx, 'tcx>(mc: &MemCategorizationContext<'a, 'gcx, 'tcx>, expr: &hir::Expr, adjustments: &[adjustment::Adjustment<'tcx>]) - -> McResult<cmt<'tcx>> { + -> McResult<cmt_<'tcx>> { match adjustments.split_last() { None => mc.cat_expr_unadjusted(expr), Some((adjustment, previous)) => { @@ -591,24 +591,24 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { } pub fn cat_expr_adjusted(&self, expr: &hir::Expr, - previous: cmt<'tcx>, + previous: cmt_<'tcx>, adjustment: &adjustment::Adjustment<'tcx>) - -> McResult<cmt<'tcx>> { + -> McResult<cmt_<'tcx>> { self.cat_expr_adjusted_with(expr, || Ok(previous), adjustment) } fn cat_expr_adjusted_with<F>(&self, expr: &hir::Expr, previous: F, adjustment: &adjustment::Adjustment<'tcx>) - -> McResult<cmt<'tcx>> - where F: FnOnce() -> McResult<cmt<'tcx>> + -> McResult<cmt_<'tcx>> + where F: FnOnce() -> McResult<cmt_<'tcx>> { debug!("cat_expr_adjusted_with({:?}): {:?}", adjustment, expr); let target = self.resolve_type_vars_if_possible(&adjustment.target); match adjustment.kind { adjustment::Adjust::Deref(overloaded) => { // Equivalent to *expr or something similar. - let base = if let Some(deref) = overloaded { + let base = Rc::new(if let Some(deref) = overloaded { let ref_ty = self.tcx.mk_ref(deref.region, ty::TypeAndMut { ty: target, mutbl: deref.mutbl, @@ -616,7 +616,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { self.cat_rvalue_node(expr.id, expr.span, ref_ty) } else { previous()? - }; + }); self.cat_deref(expr, base, false) } @@ -633,7 +633,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { } } - pub fn cat_expr_unadjusted(&self, expr: &hir::Expr) -> McResult<cmt<'tcx>> { + pub fn cat_expr_unadjusted(&self, expr: &hir::Expr) -> McResult<cmt_<'tcx>> { debug!("cat_expr: id={} expr={:?}", expr.id, expr); let expr_ty = self.expr_ty(expr)?; @@ -642,13 +642,13 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { if self.tables.is_method_call(expr) { self.cat_overloaded_place(expr, e_base, false) } else { - let base_cmt = self.cat_expr(&e_base)?; + let base_cmt = Rc::new(self.cat_expr(&e_base)?); self.cat_deref(expr, base_cmt, false) } } hir::ExprField(ref base, f_name) => { - let base_cmt = self.cat_expr(&base)?; + let base_cmt = Rc::new(self.cat_expr(&base)?); debug!("cat_expr(cat_field): id={} expr={:?} base={:?}", expr.id, expr, @@ -666,7 +666,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // dereferencing. self.cat_overloaded_place(expr, base, true) } else { - let base_cmt = self.cat_expr(&base)?; + let base_cmt = Rc::new(self.cat_expr(&base)?); self.cat_index(expr, base_cmt, expr_ty, InteriorOffsetKind::Index) } } @@ -701,7 +701,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { span: Span, expr_ty: Ty<'tcx>, def: Def) - -> McResult<cmt<'tcx>> { + -> McResult<cmt_<'tcx>> { debug!("cat_def: id={} expr={:?} def={:?}", id, expr_ty, def); @@ -718,14 +718,14 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { return Ok(self.cat_rvalue_node(id, span, expr_ty)); } } - Ok(Rc::new(cmt_ { + Ok(cmt_ { id:id, span:span, cat:Categorization::StaticItem, mutbl: if mutbl { McDeclared } else { McImmutable}, ty:expr_ty, note: NoteNone - })) + }) } Def::Upvar(var_id, _, fn_node_id) => { @@ -733,14 +733,14 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { } Def::Local(vid) => { - Ok(Rc::new(cmt_ { + Ok(cmt_ { id, span, cat: Categorization::Local(vid), mutbl: MutabilityCategory::from_local(self.tcx, self.tables, vid), ty: expr_ty, note: NoteNone - })) + }) } def => span_bug!(span, "unexpected definition in memory categorization: {:?}", def) @@ -754,7 +754,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { span: Span, var_id: ast::NodeId, fn_node_id: ast::NodeId) - -> McResult<cmt<'tcx>> + -> McResult<cmt_<'tcx>> { let fn_hir_id = self.tcx.hir.node_to_hir_id(fn_node_id); @@ -861,7 +861,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { } }; - let ret = Rc::new(cmt_result); + let ret = cmt_result; debug!("cat_upvar ret={:?}", ret); Ok(ret) } @@ -938,7 +938,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { id: ast::NodeId, span: Span, expr_ty: Ty<'tcx>) - -> cmt<'tcx> { + -> cmt_<'tcx> { let hir_id = self.tcx.hir.node_to_hir_id(id); let promotable = self.rvalue_promotable_map.as_ref().map(|m| m.contains(&hir_id.local_id)) .unwrap_or(false); @@ -966,15 +966,15 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { cmt_id: ast::NodeId, span: Span, temp_scope: ty::Region<'tcx>, - expr_ty: Ty<'tcx>) -> cmt<'tcx> { - let ret = Rc::new(cmt_ { + expr_ty: Ty<'tcx>) -> cmt_<'tcx> { + let ret = cmt_ { id:cmt_id, span:span, cat:Categorization::Rvalue(temp_scope), mutbl:McDeclared, ty:expr_ty, note: NoteNone - }); + }; debug!("cat_rvalue ret {:?}", ret); ret } @@ -985,15 +985,15 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { f_index: usize, f_name: Name, f_ty: Ty<'tcx>) - -> cmt<'tcx> { - let ret = Rc::new(cmt_ { + -> cmt_<'tcx> { + let ret = cmt_ { id: node.id(), span: node.span(), mutbl: base_cmt.mutbl.inherit(), cat: Categorization::Interior(base_cmt, InteriorField(FieldIndex(f_index, f_name))), ty: f_ty, note: NoteNone - }); + }; debug!("cat_field ret {:?}", ret); ret } @@ -1002,7 +1002,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { expr: &hir::Expr, base: &hir::Expr, implicit: bool) - -> McResult<cmt<'tcx>> { + -> McResult<cmt_<'tcx>> { debug!("cat_overloaded_place: implicit={}", implicit); // Reconstruct the output assuming it's a reference with the @@ -1022,7 +1022,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { mutbl, }); - let base_cmt = self.cat_rvalue_node(expr.id, expr.span, ref_ty); + let base_cmt = Rc::new(self.cat_rvalue_node(expr.id, expr.span, ref_ty)); self.cat_deref(expr, base_cmt, implicit) } @@ -1030,7 +1030,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { node: &N, base_cmt: cmt<'tcx>, implicit: bool) - -> McResult<cmt<'tcx>> { + -> McResult<cmt_<'tcx>> { debug!("cat_deref: base_cmt={:?}", base_cmt); let base_cmt_ty = base_cmt.ty; @@ -1052,7 +1052,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { } ref ty => bug!("unexpected type in cat_deref: {:?}", ty) }; - let ret = Rc::new(cmt_ { + let ret = cmt_ { id: node.id(), span: node.span(), // For unique ptrs, we inherit mutability from the owning reference. @@ -1060,7 +1060,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { cat: Categorization::Deref(base_cmt, ptr), ty: deref_ty, note: NoteNone - }); + }; debug!("cat_deref ret {:?}", ret); Ok(ret) } @@ -1070,7 +1070,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { base_cmt: cmt<'tcx>, element_ty: Ty<'tcx>, context: InteriorOffsetKind) - -> McResult<cmt<'tcx>> { + -> McResult<cmt_<'tcx>> { //! Creates a cmt for an indexing operation (`[]`). //! //! One subtle aspect of indexing that may not be @@ -1089,8 +1089,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { //! - `base_cmt`: the cmt of `elt` let interior_elem = InteriorElement(context); - let ret = - self.cat_imm_interior(elt, base_cmt, element_ty, interior_elem); + let ret = self.cat_imm_interior(elt, base_cmt, element_ty, interior_elem); debug!("cat_index ret {:?}", ret); return Ok(ret); } @@ -1100,15 +1099,15 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { base_cmt: cmt<'tcx>, interior_ty: Ty<'tcx>, interior: InteriorKind) - -> cmt<'tcx> { - let ret = Rc::new(cmt_ { + -> cmt_<'tcx> { + let ret = cmt_ { id: node.id(), span: node.span(), mutbl: base_cmt.mutbl.inherit(), cat: Categorization::Interior(base_cmt, interior), ty: interior_ty, note: NoteNone - }); + }; debug!("cat_imm_interior ret={:?}", ret); ret } @@ -1232,7 +1231,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { .get(pat.hir_id) .map(|v| v.len()) .unwrap_or(0) { - cmt = self.cat_deref(pat, cmt, true /* implicit */)?; + cmt = Rc::new(self.cat_deref(pat, cmt, true /* implicit */)?); } let cmt = cmt; // lose mutability @@ -1279,7 +1278,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) { let subpat_ty = self.pat_ty(&subpat)?; // see (*2) let interior = InteriorField(FieldIndex(i, Name::intern(&i.to_string()))); - let subcmt = self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior); + let subcmt = Rc::new(self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior)); self.cat_pattern_(subcmt, &subpat, op)?; } } @@ -1302,7 +1301,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { for fp in field_pats { let field_ty = self.pat_ty(&fp.node.pat)?; // see (*2) let f_index = self.tcx.field_index(fp.node.id, self.tables); - let cmt_field = self.cat_field(pat, cmt.clone(), f_index, fp.node.name, field_ty); + let cmt_field = + Rc::new(self.cat_field(pat, cmt.clone(), f_index, fp.node.name, field_ty)); self.cat_pattern_(cmt_field, &fp.node.pat, op)?; } } @@ -1320,7 +1320,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) { let subpat_ty = self.pat_ty(&subpat)?; // see (*2) let interior = InteriorField(FieldIndex(i, Name::intern(&i.to_string()))); - let subcmt = self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior); + let subcmt = Rc::new(self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior)); self.cat_pattern_(subcmt, &subpat, op)?; } } @@ -1329,7 +1329,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // box p1, &p1, &mut p1. we can ignore the mutability of // PatKind::Ref since that information is already contained // in the type. - let subcmt = self.cat_deref(pat, cmt, false)?; + let subcmt = Rc::new(self.cat_deref(pat, cmt, false)?); self.cat_pattern_(subcmt, &subpat, op)?; } @@ -1342,7 +1342,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { } }; let context = InteriorOffsetKind::Pattern; - let elt_cmt = self.cat_index(pat, cmt, element_ty, context)?; + let elt_cmt = Rc::new(self.cat_index(pat, cmt, element_ty, context)?); for before_pat in before { self.cat_pattern_(elt_cmt.clone(), &before_pat, op)?; } @@ -1379,7 +1379,7 @@ pub enum AliasableReason { } impl<'tcx> cmt_<'tcx> { - pub fn guarantor(&self) -> cmt<'tcx> { + pub fn guarantor(&self) -> cmt_<'tcx> { //! Returns `self` after stripping away any derefs or //! interior content. The return value is basically the `cmt` which //! determines how long the value in `self` remains live. @@ -1392,7 +1392,7 @@ impl<'tcx> cmt_<'tcx> { Categorization::Deref(_, BorrowedPtr(..)) | Categorization::Deref(_, Implicit(..)) | Categorization::Upvar(..) => { - Rc::new((*self).clone()) + (*self).clone() } Categorization::Downcast(ref b, _) | Categorization::Interior(ref b, _) | @@ -1442,16 +1442,17 @@ impl<'tcx> cmt_<'tcx> { } } - // Digs down through one or two layers of deref and grabs the cmt - // for the upvar if a note indicates there is one. - pub fn upvar(&self) -> Option<cmt<'tcx>> { + // Digs down through one or two layers of deref and grabs the + // Categorization of the cmt for the upvar if a note indicates there is + // one. + pub fn upvar_cat(&self) -> Option<&Categorization<'tcx>> { match self.note { NoteClosureEnv(..) | NoteUpvarRef(..) => { Some(match self.cat { Categorization::Deref(ref inner, _) => { match inner.cat { - Categorization::Deref(ref inner, _) => inner.clone(), - Categorization::Upvar(..) => inner.clone(), + Categorization::Deref(ref inner, _) => &inner.cat, + Categorization::Upvar(..) => &inner.cat, _ => bug!() } } @@ -1462,7 +1463,6 @@ impl<'tcx> cmt_<'tcx> { } } - pub fn descriptive_string(&self, tcx: TyCtxt) -> String { match self.cat { Categorization::StaticItem => { @@ -1479,8 +1479,7 @@ impl<'tcx> cmt_<'tcx> { } } Categorization::Deref(_, pk) => { - let upvar = self.upvar(); - match upvar.as_ref().map(|i| &i.cat) { + match self.upvar_cat() { Some(&Categorization::Upvar(ref var)) => { var.to_string() } diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index a01b3cbf47bee..79baf0ec15178 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -99,7 +99,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> { fn consume(&mut self, consume_id: ast::NodeId, consume_span: Span, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, mode: euv::ConsumeMode) { debug!("consume(consume_id={}, cmt={:?}, mode={:?})", consume_id, cmt, mode); @@ -110,12 +110,12 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> { fn matched_pat(&mut self, _matched_pat: &hir::Pat, - _cmt: mc::cmt, + _cmt: &mc::cmt_, _mode: euv::MatchMode) { } fn consume_pat(&mut self, consume_pat: &hir::Pat, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, mode: euv::ConsumeMode) { debug!("consume_pat(consume_pat={:?}, cmt={:?}, mode={:?})", consume_pat, @@ -128,7 +128,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> { fn borrow(&mut self, borrow_id: ast::NodeId, borrow_span: Span, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, loan_region: ty::Region<'tcx>, bk: ty::BorrowKind, loan_cause: euv::LoanCause) @@ -139,7 +139,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> { bk, loan_cause); let hir_id = self.tcx().hir.node_to_hir_id(borrow_id); - if let Some(lp) = opt_loan_path(&cmt) { + if let Some(lp) = opt_loan_path(cmt) { let moved_value_use_kind = match loan_cause { euv::ClosureCapture(_) => MovedInCapture, _ => MovedInUse, @@ -155,13 +155,13 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> { fn mutate(&mut self, assignment_id: ast::NodeId, assignment_span: Span, - assignee_cmt: mc::cmt<'tcx>, + assignee_cmt: &mc::cmt_<'tcx>, mode: euv::MutateMode) { debug!("mutate(assignment_id={}, assignee_cmt={:?})", assignment_id, assignee_cmt); - if let Some(lp) = opt_loan_path(&assignee_cmt) { + if let Some(lp) = opt_loan_path(assignee_cmt) { match mode { MutateMode::Init | MutateMode::JustWrite => { // In a case like `path = 1`, then path does not @@ -363,10 +363,10 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { } pub fn check_for_loans_across_yields(&self, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, loan_region: ty::Region<'tcx>, borrow_span: Span) { - pub fn borrow_of_local_data<'tcx>(cmt: &mc::cmt<'tcx>) -> bool { + pub fn borrow_of_local_data<'tcx>(cmt: &mc::cmt_<'tcx>) -> bool { match cmt.cat { // Borrows of static items is allowed Categorization::StaticItem => false, @@ -401,7 +401,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { return; } - if !borrow_of_local_data(&cmt) { + if !borrow_of_local_data(cmt) { return; } @@ -649,9 +649,9 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { fn consume_common(&self, id: hir::ItemLocalId, span: Span, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, mode: euv::ConsumeMode) { - if let Some(lp) = opt_loan_path(&cmt) { + if let Some(lp) = opt_loan_path(cmt) { let moved_value_use_kind = match mode { euv::Copy => { self.check_for_copy_of_frozen_path(id, span, &lp); @@ -876,11 +876,11 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { fn check_assignment(&self, assignment_id: hir::ItemLocalId, assignment_span: Span, - assignee_cmt: mc::cmt<'tcx>) { + assignee_cmt: &mc::cmt_<'tcx>) { debug!("check_assignment(assignee_cmt={:?})", assignee_cmt); // Check that we don't invalidate any outstanding loans - if let Some(loan_path) = opt_loan_path(&assignee_cmt) { + if let Some(loan_path) = opt_loan_path(assignee_cmt) { let scope = region::Scope::Node(assignment_id); self.each_in_scope_loan_affecting_path(scope, &loan_path, |loan| { self.report_illegal_mutation(assignment_span, &loan_path, loan); @@ -892,7 +892,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { // needs to be done here instead of in check_loans because we // depend on move data. if let Categorization::Local(local_id) = assignee_cmt.cat { - let lp = opt_loan_path(&assignee_cmt).unwrap(); + let lp = opt_loan_path(assignee_cmt).unwrap(); self.move_data.each_assignment_of(assignment_id, &lp, |assign| { if assignee_cmt.mutbl.is_mutable() { let hir_id = self.bccx.tcx.hir.node_to_hir_id(local_id); diff --git a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs index 465457f5ab39a..ac905d6de5d3c 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs @@ -26,10 +26,10 @@ use syntax_pos::Span; use rustc::hir::*; use rustc::hir::map::Node::*; -struct GatherMoveInfo<'tcx> { +struct GatherMoveInfo<'c, 'tcx: 'c> { id: hir::ItemLocalId, kind: MoveKind, - cmt: mc::cmt<'tcx>, + cmt: &'c mc::cmt_<'tcx>, span_path_opt: Option<MovePlace<'tcx>> } @@ -87,7 +87,7 @@ pub fn gather_move_from_expr<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, move_data: &MoveData<'tcx>, move_error_collector: &mut MoveErrorCollector<'tcx>, move_expr_id: hir::ItemLocalId, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, move_reason: euv::MoveReason) { let kind = match move_reason { euv::DirectRefMove | euv::PatBindingMove => MoveExpr, @@ -102,11 +102,11 @@ pub fn gather_move_from_expr<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, gather_move(bccx, move_data, move_error_collector, move_info); } -pub fn gather_move_from_pat<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, - move_data: &MoveData<'tcx>, - move_error_collector: &mut MoveErrorCollector<'tcx>, - move_pat: &hir::Pat, - cmt: mc::cmt<'tcx>) { +pub fn gather_move_from_pat<'a, 'c, 'tcx: 'c>(bccx: &BorrowckCtxt<'a, 'tcx>, + move_data: &MoveData<'tcx>, + move_error_collector: &mut MoveErrorCollector<'tcx>, + move_pat: &hir::Pat, + cmt: &'c mc::cmt_<'tcx>) { let source = get_pattern_source(bccx.tcx,move_pat); let pat_span_path_opt = match move_pat.node { PatKind::Binding(_, _, ref path1, _) => { @@ -132,18 +132,17 @@ pub fn gather_move_from_pat<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, gather_move(bccx, move_data, move_error_collector, move_info); } -fn gather_move<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, +fn gather_move<'a, 'c, 'tcx: 'c>(bccx: &BorrowckCtxt<'a, 'tcx>, move_data: &MoveData<'tcx>, move_error_collector: &mut MoveErrorCollector<'tcx>, - move_info: GatherMoveInfo<'tcx>) { + move_info: GatherMoveInfo<'c, 'tcx>) { debug!("gather_move(move_id={:?}, cmt={:?})", move_info.id, move_info.cmt); - let potentially_illegal_move = - check_and_get_illegal_move_origin(bccx, &move_info.cmt); + let potentially_illegal_move = check_and_get_illegal_move_origin(bccx, move_info.cmt); if let Some(illegal_move_origin) = potentially_illegal_move { debug!("illegal_move_origin={:?}", illegal_move_origin); - let error = MoveError::with_move_info(illegal_move_origin, + let error = MoveError::with_move_info(Rc::new(illegal_move_origin), move_info.span_path_opt); move_error_collector.add_error(error); return; @@ -177,8 +176,8 @@ pub fn gather_assignment<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, // (keep in sync with move_error::report_cannot_move_out_of ) fn check_and_get_illegal_move_origin<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, - cmt: &mc::cmt<'tcx>) - -> Option<mc::cmt<'tcx>> { + cmt: &mc::cmt_<'tcx>) + -> Option<mc::cmt_<'tcx>> { match cmt.cat { Categorization::Deref(_, mc::BorrowedPtr(..)) | Categorization::Deref(_, mc::Implicit(..)) | diff --git a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs index 97fa94b5e5cf9..6d73500d31802 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs @@ -27,7 +27,7 @@ pub fn guarantee_lifetime<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, item_scope: region::Scope, span: Span, cause: euv::LoanCause, - cmt: mc::cmt<'tcx>, + cmt: &'a mc::cmt_<'tcx>, loan_region: ty::Region<'tcx>, _: ty::BorrowKind) -> Result<(),()> { @@ -41,8 +41,8 @@ pub fn guarantee_lifetime<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, span, cause, loan_region, - cmt_original: cmt.clone()}; - ctxt.check(&cmt, None) + cmt_original: cmt}; + ctxt.check(cmt, None) } /////////////////////////////////////////////////////////////////////////// @@ -57,12 +57,11 @@ struct GuaranteeLifetimeContext<'a, 'tcx: 'a> { span: Span, cause: euv::LoanCause, loan_region: ty::Region<'tcx>, - cmt_original: mc::cmt<'tcx> + cmt_original: &'a mc::cmt_<'tcx> } impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { - - fn check(&self, cmt: &mc::cmt<'tcx>, discr_scope: Option<ast::NodeId>) -> R { + fn check(&self, cmt: &mc::cmt_<'tcx>, discr_scope: Option<ast::NodeId>) -> R { //! Main routine. Walks down `cmt` until we find the //! "guarantor". Reports an error if `self.loan_region` is //! larger than scope of `cmt`. @@ -102,7 +101,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { } } - fn scope(&self, cmt: &mc::cmt<'tcx>) -> ty::Region<'tcx> { + fn scope(&self, cmt: &mc::cmt_<'tcx>) -> ty::Region<'tcx> { //! Returns the maximal region scope for the which the //! place `cmt` is guaranteed to be valid without any //! rooting etc, and presuming `cmt` is not mutated. @@ -136,7 +135,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { } fn report_error(&self, code: bckerr_code<'tcx>) { - self.bccx.report(BckError { cmt: self.cmt_original.clone(), + self.bccx.report(BckError { cmt: self.cmt_original, span: self.span, cause: BorrowViolation(self.cause), code: code }); diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 49234f4ed7fde..a74eba3995518 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -76,7 +76,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> { fn consume(&mut self, consume_id: ast::NodeId, _consume_span: Span, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, mode: euv::ConsumeMode) { debug!("consume(consume_id={}, cmt={:?}, mode={:?})", consume_id, cmt, mode); @@ -93,7 +93,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> { fn matched_pat(&mut self, matched_pat: &hir::Pat, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, mode: euv::MatchMode) { debug!("matched_pat(matched_pat={:?}, cmt={:?}, mode={:?})", matched_pat, @@ -103,7 +103,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> { fn consume_pat(&mut self, consume_pat: &hir::Pat, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, mode: euv::ConsumeMode) { debug!("consume_pat(consume_pat={:?}, cmt={:?}, mode={:?})", consume_pat, @@ -123,7 +123,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> { fn borrow(&mut self, borrow_id: ast::NodeId, borrow_span: Span, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, loan_region: ty::Region<'tcx>, bk: ty::BorrowKind, loan_cause: euv::LoanCause) @@ -144,7 +144,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> { fn mutate(&mut self, assignment_id: ast::NodeId, assignment_span: Span, - assignee_cmt: mc::cmt<'tcx>, + assignee_cmt: &mc::cmt_<'tcx>, mode: euv::MutateMode) { self.guarantee_assignment_valid(assignment_id, @@ -165,7 +165,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> { fn check_aliasability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, borrow_span: Span, loan_cause: AliasableViolationKind, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, req_kind: ty::BorrowKind) -> Result<(),()> { @@ -206,7 +206,7 @@ fn check_aliasability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, fn check_mutability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, borrow_span: Span, cause: AliasableViolationKind, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, req_kind: ty::BorrowKind) -> Result<(),()> { debug!("check_mutability(cause={:?} cmt={:?} req_kind={:?}", @@ -246,10 +246,10 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { fn guarantee_assignment_valid(&mut self, assignment_id: ast::NodeId, assignment_span: Span, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, mode: euv::MutateMode) { - let opt_lp = opt_loan_path(&cmt); + let opt_lp = opt_loan_path(cmt); debug!("guarantee_assignment_valid(assignment_id={}, cmt={:?}) opt_lp={:?}", assignment_id, cmt, opt_lp); @@ -259,14 +259,14 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { } else { // Check that we don't allow assignments to non-mutable data. if check_mutability(self.bccx, assignment_span, MutabilityViolation, - cmt.clone(), ty::MutBorrow).is_err() { + cmt, ty::MutBorrow).is_err() { return; // reported an error, no sense in reporting more. } } // Check that we don't allow assignments to aliasable data if check_aliasability(self.bccx, assignment_span, MutabilityViolation, - cmt.clone(), ty::MutBorrow).is_err() { + cmt, ty::MutBorrow).is_err() { return; // reported an error, no sense in reporting more. } @@ -300,7 +300,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { fn guarantee_valid(&mut self, borrow_id: hir::ItemLocalId, borrow_span: Span, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, req_kind: ty::BorrowKind, loan_region: ty::Region<'tcx>, cause: euv::LoanCause) { @@ -320,28 +320,26 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { // Check that the lifetime of the borrow does not exceed // the lifetime of the data being borrowed. if lifetime::guarantee_lifetime(self.bccx, self.item_ub, - borrow_span, cause, cmt.clone(), loan_region, - req_kind).is_err() { + borrow_span, cause, cmt, loan_region, req_kind).is_err() { return; // reported an error, no sense in reporting more. } // Check that we don't allow mutable borrows of non-mutable data. if check_mutability(self.bccx, borrow_span, BorrowViolation(cause), - cmt.clone(), req_kind).is_err() { + cmt, req_kind).is_err() { return; // reported an error, no sense in reporting more. } // Check that we don't allow mutable borrows of aliasable data. if check_aliasability(self.bccx, borrow_span, BorrowViolation(cause), - cmt.clone(), req_kind).is_err() { + cmt, req_kind).is_err() { return; // reported an error, no sense in reporting more. } // Compute the restrictions that are required to enforce the // loan is safe. let restr = restrictions::compute_restrictions( - self.bccx, borrow_span, cause, - cmt.clone(), loan_region); + self.bccx, borrow_span, cause, &cmt, loan_region); debug!("guarantee_valid(): restrictions={:?}", restr); diff --git a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs index e3adb51433b25..0b90127cc7e1e 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs @@ -30,7 +30,7 @@ pub enum RestrictionResult<'tcx> { pub fn compute_restrictions<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, span: Span, cause: euv::LoanCause, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, loan_region: ty::Region<'tcx>) -> RestrictionResult<'tcx> { let ctxt = RestrictionsContext { @@ -55,7 +55,7 @@ struct RestrictionsContext<'a, 'tcx: 'a> { impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> { fn restrict(&self, - cmt: mc::cmt<'tcx>) -> RestrictionResult<'tcx> { + cmt: &mc::cmt_<'tcx>) -> RestrictionResult<'tcx> { debug!("restrict(cmt={:?})", cmt); let new_lp = |v: LoanPathKind<'tcx>| Rc::new(LoanPath::new(v, cmt.ty)); @@ -86,7 +86,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> { // When we borrow the interior of an enum, we have to // ensure the enum itself is not mutated, because that // could cause the type of the memory to change. - self.restrict(cmt_base) + self.restrict(&cmt_base) } Categorization::Interior(cmt_base, interior) => { @@ -101,7 +101,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> { }; let interior = interior.cleaned(); let base_ty = cmt_base.ty; - let result = self.restrict(cmt_base); + let result = self.restrict(&cmt_base); // Borrowing one union field automatically borrows all its fields. match base_ty.sty { ty::TyAdt(adt_def, _) if adt_def.is_union() => match result { @@ -145,7 +145,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> { // // Eventually we should make these non-special and // just rely on Deref<T> implementation. - let result = self.restrict(cmt_base); + let result = self.restrict(&cmt_base); self.extend(result, &cmt, LpDeref(pk)) } mc::Implicit(bk, lt) | mc::BorrowedPtr(bk, lt) => { @@ -155,7 +155,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> { BckError { span: self.span, cause: BorrowViolation(self.cause), - cmt: cmt_base, + cmt: &cmt_base, code: err_borrowed_pointer_too_short( self.loan_region, lt)}); return RestrictionResult::Safe; @@ -169,7 +169,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> { // The referent can be aliased after the // references lifetime ends (by a newly-unfrozen // borrow). - let result = self.restrict(cmt_base); + let result = self.restrict(&cmt_base); self.extend(result, &cmt, LpDeref(pk)) } } @@ -183,7 +183,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> { fn extend(&self, result: RestrictionResult<'tcx>, - cmt: &mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, elem: LoanPathElem<'tcx>) -> RestrictionResult<'tcx> { match result { RestrictionResult::Safe => RestrictionResult::Safe, diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 6d832d4060a1f..98235b2920fdf 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -497,7 +497,7 @@ impl<'a, 'tcx> LoanPath<'tcx> { // Avoid "cannot borrow immutable field `self.x` as mutable" as that implies that a field *can* be // mutable independently of the struct it belongs to. (#35937) -pub fn opt_loan_path_is_field<'tcx>(cmt: &mc::cmt<'tcx>) -> (Option<Rc<LoanPath<'tcx>>>, bool) { +pub fn opt_loan_path_is_field<'tcx>(cmt: &mc::cmt_<'tcx>) -> (Option<Rc<LoanPath<'tcx>>>, bool) { let new_lp = |v: LoanPathKind<'tcx>| Rc::new(LoanPath::new(v, cmt.ty)); match cmt.cat { @@ -545,7 +545,7 @@ pub fn opt_loan_path_is_field<'tcx>(cmt: &mc::cmt<'tcx>) -> (Option<Rc<LoanPath< /// the method `compute()` found in `gather_loans::restrictions`, /// which allows it to share common loan path pieces as it /// traverses the CMT. -pub fn opt_loan_path<'tcx>(cmt: &mc::cmt<'tcx>) -> Option<Rc<LoanPath<'tcx>>> { +pub fn opt_loan_path<'tcx>(cmt: &mc::cmt_<'tcx>) -> Option<Rc<LoanPath<'tcx>>> { opt_loan_path_is_field(cmt).0 } @@ -564,10 +564,10 @@ pub enum bckerr_code<'tcx> { // Combination of an error code and the categorization of the expression // that caused it #[derive(Debug, PartialEq)] -pub struct BckError<'tcx> { +pub struct BckError<'c, 'tcx: 'c> { span: Span, cause: AliasableViolationKind, - cmt: mc::cmt<'tcx>, + cmt: &'c mc::cmt_<'tcx>, code: bckerr_code<'tcx> } @@ -599,7 +599,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { region_rels.is_subregion_of(r_sub, r_sup) } - pub fn report(&self, err: BckError<'tcx>) { + pub fn report(&self, err: BckError<'a, 'tcx>) { // Catch and handle some particular cases. match (&err.code, &err.cause) { (&err_out_of_scope(&ty::ReScope(_), &ty::ReStatic, _), @@ -800,7 +800,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { self.tcx.sess.span_err_with_code(s, msg, code); } - fn report_bckerr(&self, err: &BckError<'tcx>) { + fn report_bckerr(&self, err: &BckError<'a, 'tcx>) { let error_span = err.span.clone(); match err.code { @@ -1011,7 +1011,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { db.emit(); } err_borrowed_pointer_too_short(loan_scope, ptr_scope) => { - let descr = self.cmt_to_path_or_string(&err.cmt); + let descr = self.cmt_to_path_or_string(err.cmt); let mut db = self.lifetime_too_short_for_reborrow(error_span, &descr, Origin::Ast); let descr = match opt_loan_path(&err.cmt) { Some(lp) => { @@ -1042,7 +1042,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { span: Span, kind: AliasableViolationKind, cause: mc::AliasableReason, - cmt: mc::cmt<'tcx>) { + cmt: &mc::cmt_<'tcx>) { let mut is_closure = false; let prefix = match kind { MutabilityViolation => { @@ -1240,7 +1240,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } fn report_out_of_scope_escaping_closure_capture(&self, - err: &BckError<'tcx>, + err: &BckError<'a, 'tcx>, capture_span: Span) { let cmt_path_or_string = self.cmt_to_path_or_string(&err.cmt); @@ -1274,18 +1274,18 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } } - fn note_and_explain_mutbl_error(&self, db: &mut DiagnosticBuilder, err: &BckError<'tcx>, + fn note_and_explain_mutbl_error(&self, db: &mut DiagnosticBuilder, err: &BckError<'a, 'tcx>, error_span: &Span) { match err.cmt.note { mc::NoteClosureEnv(upvar_id) | mc::NoteUpvarRef(upvar_id) => { // If this is an `Fn` closure, it simply can't mutate upvars. // If it's an `FnMut` closure, the original variable was declared immutable. // We need to determine which is the case here. - let kind = match err.cmt.upvar().unwrap().cat { + let kind = match err.cmt.upvar_cat().unwrap() { Categorization::Upvar(mc::Upvar { kind, .. }) => kind, _ => bug!() }; - if kind == ty::ClosureKind::Fn { + if *kind == ty::ClosureKind::Fn { let closure_node_id = self.tcx.hir.local_def_id_to_node_id(upvar_id.closure_expr_id); db.span_help(self.tcx.hir.span(closure_node_id), @@ -1389,7 +1389,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { cmt.descriptive_string(self.tcx) } - pub fn cmt_to_path_or_string(&self, cmt: &mc::cmt<'tcx>) -> String { + pub fn cmt_to_path_or_string(&self, cmt: &mc::cmt_<'tcx>) -> String { match opt_loan_path(cmt) { Some(lp) => format!("`{}`", self.loan_path_to_string(&lp)), None => self.cmt_to_string(cmt), diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index d924baaf00521..77bcd88cecb6e 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -17,7 +17,7 @@ use super::{Pattern, PatternContext, PatternError, PatternKind}; use rustc::middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor}; use rustc::middle::expr_use_visitor::{LoanCause, MutateMode}; use rustc::middle::expr_use_visitor as euv; -use rustc::middle::mem_categorization::{cmt}; +use rustc::middle::mem_categorization::cmt_; use rustc::middle::region; use rustc::session::Session; use rustc::ty::{self, Ty, TyCtxt}; @@ -573,13 +573,13 @@ struct MutationChecker<'a, 'tcx: 'a> { } impl<'a, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'tcx> { - fn matched_pat(&mut self, _: &Pat, _: cmt, _: euv::MatchMode) {} - fn consume(&mut self, _: ast::NodeId, _: Span, _: cmt, _: ConsumeMode) {} - fn consume_pat(&mut self, _: &Pat, _: cmt, _: ConsumeMode) {} + fn matched_pat(&mut self, _: &Pat, _: &cmt_, _: euv::MatchMode) {} + fn consume(&mut self, _: ast::NodeId, _: Span, _: &cmt_, _: ConsumeMode) {} + fn consume_pat(&mut self, _: &Pat, _: &cmt_, _: ConsumeMode) {} fn borrow(&mut self, _: ast::NodeId, span: Span, - _: cmt, + _: &cmt_, _: ty::Region<'tcx>, kind:ty:: BorrowKind, _: LoanCause) { @@ -594,7 +594,7 @@ impl<'a, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'tcx> { } } fn decl_without_init(&mut self, _: ast::NodeId, _: Span) {} - fn mutate(&mut self, _: ast::NodeId, span: Span, _: cmt, mode: MutateMode) { + fn mutate(&mut self, _: ast::NodeId, span: Span, _: &cmt_, mode: MutateMode) { match mode { MutateMode::JustWrite | MutateMode::WriteAndRead => { struct_span_err!(self.cx.tcx.sess, span, E0302, "cannot assign in a pattern guard") diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index c5d2f0041a0f2..3a577341f7e01 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -468,13 +468,13 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'gcx> { fn consume(&mut self, _consume_id: ast::NodeId, _consume_span: Span, - _cmt: mc::cmt, + _cmt: &mc::cmt_, _mode: euv::ConsumeMode) {} fn borrow(&mut self, borrow_id: ast::NodeId, _borrow_span: Span, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, _loan_region: ty::Region<'tcx>, bk: ty::BorrowKind, loan_cause: euv::LoanCause) { @@ -489,7 +489,7 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'gcx> { _ => {} } - let mut cur = &cmt; + let mut cur = cmt; loop { match cur.cat { Categorization::Rvalue(..) => { @@ -521,11 +521,11 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'gcx> { fn mutate(&mut self, _assignment_id: ast::NodeId, _assignment_span: Span, - _assignee_cmt: mc::cmt, + _assignee_cmt: &mc::cmt_, _mode: euv::MutateMode) { } - fn matched_pat(&mut self, _: &hir::Pat, _: mc::cmt, _: euv::MatchMode) {} + fn matched_pat(&mut self, _: &hir::Pat, _: &mc::cmt_, _: euv::MatchMode) {} - fn consume_pat(&mut self, _consume_pat: &hir::Pat, _cmt: mc::cmt, _mode: euv::ConsumeMode) {} + fn consume_pat(&mut self, _consume_pat: &hir::Pat, _cmt: &mc::cmt_, _mode: euv::ConsumeMode) {} } diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index b5e862fac958a..e7e70a19e496b 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -96,6 +96,7 @@ use rustc::ty::adjustment; use std::mem; use std::ops::Deref; +use std::rc::Rc; use rustc_data_structures::sync::Lrc; use syntax::ast; use syntax_pos::Span; @@ -513,7 +514,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { // the adjusted form if there is an adjustment. match cmt_result { Ok(head_cmt) => { - self.check_safety_of_rvalue_destructor_if_necessary(head_cmt, expr.span); + self.check_safety_of_rvalue_destructor_if_necessary(&head_cmt, expr.span); } Err(..) => { self.tcx.sess.delay_span_bug(expr.span, "cat_expr Errd"); @@ -799,7 +800,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { /// Invoked on any adjustments that occur. Checks that if this is a region pointer being /// dereferenced, the lifetime of the pointer includes the deref expr. - fn constrain_adjustments(&mut self, expr: &hir::Expr) -> mc::McResult<mc::cmt<'tcx>> { + fn constrain_adjustments(&mut self, expr: &hir::Expr) -> mc::McResult<mc::cmt_<'tcx>> { debug!("constrain_adjustments(expr={:?})", expr); let mut cmt = self.with_mc(|mc| mc.cat_expr_unadjusted(expr))?; @@ -814,7 +815,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { // If necessary, constrain destructors in the unadjusted form of this // expression. - self.check_safety_of_rvalue_destructor_if_necessary(cmt.clone(), expr.span); + self.check_safety_of_rvalue_destructor_if_necessary(&cmt, expr.span); let expr_region = self.tcx.mk_region(ty::ReScope( region::Scope::Node(expr.hir_id.local_id))); @@ -837,7 +838,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { }); self.link_region(expr.span, deref.region, - ty::BorrowKind::from_mutbl(deref.mutbl), cmt.clone()); + ty::BorrowKind::from_mutbl(deref.mutbl), &cmt); // Specialized version of constrain_call. self.type_must_outlive(infer::CallRcvr(expr.span), @@ -847,7 +848,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { } if let adjustment::Adjust::Borrow(ref autoref) = adjustment.kind { - self.link_autoref(expr, cmt.clone(), autoref); + self.link_autoref(expr, &cmt, autoref); // Require that the resulting region encompasses // the current node. @@ -878,7 +879,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { } fn check_safety_of_rvalue_destructor_if_necessary(&mut self, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, span: Span) { match cmt.cat { Categorization::Rvalue(region) => { @@ -980,7 +981,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { debug!("link_addr_of: cmt={:?}", cmt); - self.link_region_from_node_type(expr.span, expr.hir_id, mutability, cmt); + self.link_region_from_node_type(expr.span, expr.hir_id, mutability, &cmt); } /// Computes the guarantors for any ref bindings in a `let` and @@ -992,7 +993,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { None => { return; } Some(ref expr) => &**expr, }; - let discr_cmt = ignore_err!(self.with_mc(|mc| mc.cat_expr(init_expr))); + let discr_cmt = Rc::new(ignore_err!(self.with_mc(|mc| mc.cat_expr(init_expr)))); self.link_pattern(discr_cmt, &local.pat); } @@ -1001,7 +1002,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { /// linked to the lifetime of its guarantor (if any). fn link_match(&self, discr: &hir::Expr, arms: &[hir::Arm]) { debug!("regionck::for_match()"); - let discr_cmt = ignore_err!(self.with_mc(|mc| mc.cat_expr(discr))); + let discr_cmt = Rc::new(ignore_err!(self.with_mc(|mc| mc.cat_expr(discr)))); debug!("discr_cmt={:?}", discr_cmt); for arm in arms { for root_pat in &arm.pats { @@ -1019,7 +1020,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { let arg_ty = self.node_ty(arg.hir_id); let re_scope = self.tcx.mk_region(ty::ReScope(body_scope)); let arg_cmt = self.with_mc(|mc| { - mc.cat_rvalue(arg.id, arg.pat.span, re_scope, arg_ty) + Rc::new(mc.cat_rvalue(arg.id, arg.pat.span, re_scope, arg_ty)) }); debug!("arg_ty={:?} arg_cmt={:?} arg={:?}", arg_ty, @@ -1044,7 +1045,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { .expect("missing binding mode"); if let ty::BindByReference(mutbl) = bm { self.link_region_from_node_type(sub_pat.span, sub_pat.hir_id, - mutbl, sub_cmt); + mutbl, &sub_cmt); } } _ => {} @@ -1057,15 +1058,14 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { /// autoref'd. fn link_autoref(&self, expr: &hir::Expr, - expr_cmt: mc::cmt<'tcx>, + expr_cmt: &mc::cmt_<'tcx>, autoref: &adjustment::AutoBorrow<'tcx>) { debug!("link_autoref(autoref={:?}, expr_cmt={:?})", autoref, expr_cmt); match *autoref { adjustment::AutoBorrow::Ref(r, m) => { - self.link_region(expr.span, r, - ty::BorrowKind::from_mutbl(m.into()), expr_cmt); + self.link_region(expr.span, r, ty::BorrowKind::from_mutbl(m.into()), expr_cmt); } adjustment::AutoBorrow::RawPtr(m) => { @@ -1081,15 +1081,14 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { span: Span, id: hir::HirId, mutbl: hir::Mutability, - cmt_borrowed: mc::cmt<'tcx>) { + cmt_borrowed: &mc::cmt_<'tcx>) { debug!("link_region_from_node_type(id={:?}, mutbl={:?}, cmt_borrowed={:?})", id, mutbl, cmt_borrowed); let rptr_ty = self.resolve_node_type(id); if let ty::TyRef(r, _) = rptr_ty.sty { debug!("rptr_ty={}", rptr_ty); - self.link_region(span, r, ty::BorrowKind::from_mutbl(mutbl), - cmt_borrowed); + self.link_region(span, r, ty::BorrowKind::from_mutbl(mutbl), cmt_borrowed); } } @@ -1101,19 +1100,19 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { span: Span, borrow_region: ty::Region<'tcx>, borrow_kind: ty::BorrowKind, - borrow_cmt: mc::cmt<'tcx>) { - let mut borrow_cmt = borrow_cmt; - let mut borrow_kind = borrow_kind; - + borrow_cmt: &mc::cmt_<'tcx>) { let origin = infer::DataBorrowed(borrow_cmt.ty, span); self.type_must_outlive(origin, borrow_cmt.ty, borrow_region); + let mut borrow_kind = borrow_kind; + let mut borrow_cmt_cat = borrow_cmt.cat.clone(); + loop { debug!("link_region(borrow_region={:?}, borrow_kind={:?}, borrow_cmt={:?})", borrow_region, borrow_kind, borrow_cmt); - match borrow_cmt.cat.clone() { + match borrow_cmt_cat { Categorization::Deref(ref_cmt, mc::Implicit(ref_kind, ref_region)) | Categorization::Deref(ref_cmt, mc::BorrowedPtr(ref_kind, ref_region)) => { match self.link_reborrowed_region(span, @@ -1121,7 +1120,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { ref_cmt, ref_region, ref_kind, borrow_cmt.note) { Some((c, k)) => { - borrow_cmt = c; + borrow_cmt_cat = c.cat.clone(); borrow_kind = k; } None => { @@ -1135,7 +1134,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { Categorization::Interior(cmt_base, _) => { // Borrowing interior or owned data requires the base // to be valid and borrowable in the same fashion. - borrow_cmt = cmt_base; + borrow_cmt_cat = cmt_base.cat.clone(); borrow_kind = borrow_kind; } diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 4fc3344dab2a9..58dc5839578f7 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -298,7 +298,8 @@ struct InferBorrowKind<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { } impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { - fn adjust_upvar_borrow_kind_for_consume(&mut self, cmt: mc::cmt<'tcx>, mode: euv::ConsumeMode) { + fn adjust_upvar_borrow_kind_for_consume(&mut self, cmt: &mc::cmt_<'tcx>, + mode: euv::ConsumeMode) { debug!( "adjust_upvar_borrow_kind_for_consume(cmt={:?}, mode={:?})", cmt, @@ -377,7 +378,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { /// Indicates that `cmt` is being directly mutated (e.g., assigned /// to). If cmt contains any by-ref upvars, this implies that /// those upvars must be borrowed using an `&mut` borrow. - fn adjust_upvar_borrow_kind_for_mut(&mut self, cmt: mc::cmt<'tcx>) { + fn adjust_upvar_borrow_kind_for_mut(&mut self, cmt: &mc::cmt_<'tcx>) { debug!("adjust_upvar_borrow_kind_for_mut(cmt={:?})", cmt); match cmt.cat.clone() { @@ -386,7 +387,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { Categorization::Downcast(base, _) => { // Interior or owned data is mutable if base is // mutable, so iterate to the base. - self.adjust_upvar_borrow_kind_for_mut(base); + self.adjust_upvar_borrow_kind_for_mut(&base); } Categorization::Deref(base, mc::BorrowedPtr(..)) | @@ -396,7 +397,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { // borrowed pointer implies that the // pointer itself must be unique, but not // necessarily *mutable* - self.adjust_upvar_borrow_kind_for_unique(base); + self.adjust_upvar_borrow_kind_for_unique(&base); } } @@ -410,7 +411,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { } } - fn adjust_upvar_borrow_kind_for_unique(&mut self, cmt: mc::cmt<'tcx>) { + fn adjust_upvar_borrow_kind_for_unique(&mut self, cmt: &mc::cmt_<'tcx>) { debug!("adjust_upvar_borrow_kind_for_unique(cmt={:?})", cmt); match cmt.cat.clone() { @@ -419,7 +420,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { Categorization::Downcast(base, _) => { // Interior or owned data is unique if base is // unique. - self.adjust_upvar_borrow_kind_for_unique(base); + self.adjust_upvar_borrow_kind_for_unique(&base); } Categorization::Deref(base, mc::BorrowedPtr(..)) | @@ -427,7 +428,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { if !self.try_adjust_upvar_deref(cmt, ty::UniqueImmBorrow) { // for a borrowed pointer to be unique, its // base must be unique - self.adjust_upvar_borrow_kind_for_unique(base); + self.adjust_upvar_borrow_kind_for_unique(&base); } } @@ -439,7 +440,9 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { } } - fn try_adjust_upvar_deref(&mut self, cmt: mc::cmt<'tcx>, borrow_kind: ty::BorrowKind) -> bool { + fn try_adjust_upvar_deref(&mut self, cmt: &mc::cmt_<'tcx>, borrow_kind: ty::BorrowKind) + -> bool + { assert!(match borrow_kind { ty::MutBorrow => true, ty::UniqueImmBorrow => true, @@ -581,17 +584,19 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'gcx, 'tcx> { &mut self, _consume_id: ast::NodeId, _consume_span: Span, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, mode: euv::ConsumeMode, ) { debug!("consume(cmt={:?},mode={:?})", cmt, mode); self.adjust_upvar_borrow_kind_for_consume(cmt, mode); } - fn matched_pat(&mut self, _matched_pat: &hir::Pat, _cmt: mc::cmt<'tcx>, _mode: euv::MatchMode) { + fn matched_pat(&mut self, _matched_pat: &hir::Pat, _cmt: &mc::cmt_<'tcx>, + _mode: euv::MatchMode) { } - fn consume_pat(&mut self, _consume_pat: &hir::Pat, cmt: mc::cmt<'tcx>, mode: euv::ConsumeMode) { + fn consume_pat(&mut self, _consume_pat: &hir::Pat, cmt: &mc::cmt_<'tcx>, + mode: euv::ConsumeMode) { debug!("consume_pat(cmt={:?},mode={:?})", cmt, mode); self.adjust_upvar_borrow_kind_for_consume(cmt, mode); } @@ -600,7 +605,7 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'gcx, 'tcx> { &mut self, borrow_id: ast::NodeId, _borrow_span: Span, - cmt: mc::cmt<'tcx>, + cmt: &mc::cmt_<'tcx>, _loan_region: ty::Region<'tcx>, bk: ty::BorrowKind, _loan_cause: euv::LoanCause, @@ -629,7 +634,7 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'gcx, 'tcx> { &mut self, _assignment_id: ast::NodeId, _assignment_span: Span, - assignee_cmt: mc::cmt<'tcx>, + assignee_cmt: &mc::cmt_<'tcx>, _mode: euv::MutateMode, ) { debug!("mutate(assignee_cmt={:?})", assignee_cmt);