1
Fork 0

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%.
This commit is contained in:
Nicholas Nethercote 2018-05-02 10:28:37 +10:00
parent f76f6fbdea
commit 7cf142f78b
12 changed files with 208 additions and 209 deletions

View file

@ -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
{

View file

@ -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()
}

View file

@ -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);

View file

@ -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(..)) |

View file

@ -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 });

View file

@ -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);

View file

@ -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,

View file

@ -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),

View file

@ -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")

View file

@ -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) {}
}

View file

@ -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;
}

View file

@ -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);