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:
parent
f76f6fbdea
commit
7cf142f78b
12 changed files with 208 additions and 209 deletions
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>,
|
||||
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: mc::cmt<'tcx>) {
|
||||
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(..)) |
|
||||
|
|
|
@ -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 });
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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) {}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue