Auto merge of #28846 - Ms2ger:categorization, r=nikomatsakis

This commit is contained in:
bors 2015-11-02 10:44:08 +00:00
commit 5b11b286bc
12 changed files with 203 additions and 193 deletions

View File

@ -32,6 +32,7 @@ use middle::def_id::DefId;
use middle::expr_use_visitor as euv;
use middle::infer;
use middle::mem_categorization as mc;
use middle::mem_categorization::Categorization;
use middle::traits;
use middle::ty::{self, Ty};
use util::nodemap::NodeMap;
@ -855,7 +856,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'tcx> {
let mut cur = &cmt;
loop {
match cur.cat {
mc::cat_static_item => {
Categorization::StaticItem => {
if self.mode != Mode::Var {
// statics cannot be consumed by value at any time, that would imply
// that they're an initializer (what a const is for) or kept in sync
@ -866,13 +867,13 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'tcx> {
}
break;
}
mc::cat_deref(ref cmt, _, _) |
mc::cat_downcast(ref cmt, _) |
mc::cat_interior(ref cmt, _) => cur = cmt,
Categorization::Deref(ref cmt, _, _) |
Categorization::Downcast(ref cmt, _) |
Categorization::Interior(ref cmt, _) => cur = cmt,
mc::cat_rvalue(..) |
mc::cat_upvar(..) |
mc::cat_local(..) => break
Categorization::Rvalue(..) |
Categorization::Upvar(..) |
Categorization::Local(..) => break
}
}
}
@ -899,7 +900,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'tcx> {
let mut is_interior = false;
loop {
match cur.cat {
mc::cat_rvalue(..) => {
Categorization::Rvalue(..) => {
if loan_cause == euv::MatchDiscriminant {
// Ignore the dummy immutable borrow created by EUV.
break;
@ -920,7 +921,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'tcx> {
self.record_borrow(borrow_id, mutbl);
break;
}
mc::cat_static_item => {
Categorization::StaticItem => {
if is_interior && self.mode != Mode::Var {
// Borrowed statics can specifically *only* have their address taken,
// not any number of other borrows such as borrowing fields, reading
@ -931,15 +932,15 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'tcx> {
}
break;
}
mc::cat_deref(ref cmt, _, _) |
mc::cat_downcast(ref cmt, _) |
mc::cat_interior(ref cmt, _) => {
Categorization::Deref(ref cmt, _, _) |
Categorization::Downcast(ref cmt, _) |
Categorization::Interior(ref cmt, _) => {
is_interior = true;
cur = cmt;
}
mc::cat_upvar(..) |
mc::cat_local(..) => break
Categorization::Upvar(..) |
Categorization::Local(..) => break
}
}
}

View File

@ -55,7 +55,7 @@
//! let inc = || x += y;
//!
//! Then when we categorize `x` (*within* the closure) we would yield a
//! result of `*x'`, effectively, where `x'` is a `cat_upvar` reference
//! result of `*x'`, effectively, where `x'` is a `Categorization::Upvar` reference
//! tied to `x`. The type of `x'` will be a borrowed pointer.
#![allow(non_camel_case_types)]
@ -68,7 +68,6 @@ pub use self::MutabilityCategory::*;
pub use self::AliasableReason::*;
pub use self::Note::*;
pub use self::deref_kind::*;
pub use self::categorization::*;
use self::Aliasability::*;
@ -89,14 +88,14 @@ use std::fmt;
use std::rc::Rc;
#[derive(Clone, PartialEq)]
pub enum categorization<'tcx> {
cat_rvalue(ty::Region), // temporary val, argument is its scope
cat_static_item,
cat_upvar(Upvar), // upvar referenced by closure env
cat_local(ast::NodeId), // local variable
cat_deref(cmt<'tcx>, usize, PointerKind), // deref of a ptr
cat_interior(cmt<'tcx>, InteriorKind), // something interior: field, tuple, etc
cat_downcast(cmt<'tcx>, DefId), // selects a particular enum variant (*1)
pub enum Categorization<'tcx> {
Rvalue(ty::Region), // temporary val, argument is its scope
StaticItem,
Upvar(Upvar), // upvar referenced by closure env
Local(ast::NodeId), // local variable
Deref(cmt<'tcx>, usize, PointerKind), // deref of a ptr
Interior(cmt<'tcx>, InteriorKind), // something interior: field, tuple, etc
Downcast(cmt<'tcx>, DefId), // selects a particular enum variant (*1)
// (*1) downcast is only required if the enum has more than one variant
}
@ -187,7 +186,7 @@ pub enum Note {
pub struct cmt_<'tcx> {
pub id: ast::NodeId, // id of expr/pat producing this value
pub span: Span, // span of same expr/pat
pub cat: categorization<'tcx>, // categorization of expr
pub cat: Categorization<'tcx>, // categorization of expr
pub mutbl: MutabilityCategory, // mutability of expr as lvalue
pub ty: Ty<'tcx>, // type of the expr (*see WARNING above*)
pub note: Note, // Note about the provenance of this cmt
@ -557,7 +556,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
Ok(Rc::new(cmt_ {
id:id,
span:span,
cat:cat_static_item,
cat:Categorization::StaticItem,
mutbl: McImmutable,
ty:expr_ty,
note: NoteNone
@ -568,7 +567,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
Ok(Rc::new(cmt_ {
id:id,
span:span,
cat:cat_static_item,
cat:Categorization::StaticItem,
mutbl: if mutbl { McDeclared } else { McImmutable},
ty:expr_ty,
note: NoteNone
@ -604,7 +603,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
Ok(Rc::new(cmt_ {
id: id,
span: span,
cat: cat_local(vid),
cat: Categorization::Local(vid),
mutbl: MutabilityCategory::from_local(self.tcx(), vid),
ty: expr_ty,
note: NoteNone
@ -624,10 +623,10 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
-> McResult<cmt<'tcx>>
{
// An upvar can have up to 3 components. We translate first to a
// `cat_upvar`, which is itself a fiction -- it represents the reference to the
// `Categorization::Upvar`, which is itself a fiction -- it represents the reference to the
// field from the environment.
//
// `cat_upvar`. Next, we add a deref through the implicit
// `Categorization::Upvar`. Next, we add a deref through the implicit
// environment pointer with an anonymous free region 'env and
// appropriate borrow kind for closure kinds that take self by
// reference. Finally, if the upvar was captured
@ -659,7 +658,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
let cmt_result = cmt_ {
id: id,
span: span,
cat: cat_upvar(Upvar {id: upvar_id, kind: kind}),
cat: Categorization::Upvar(Upvar {id: upvar_id, kind: kind}),
mutbl: var_mutbl,
ty: var_ty,
note: NoteNone
@ -695,7 +694,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
cmt_ {
id: id,
span: span,
cat: cat_deref(Rc::new(cmt_result), 0, ptr),
cat: Categorization::Deref(Rc::new(cmt_result), 0, ptr),
mutbl: MutabilityCategory::from_borrow_kind(upvar_borrow.kind),
ty: var_ty,
note: NoteUpvarRef(upvar_id)
@ -769,7 +768,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
let ret = cmt_ {
id: id,
span: span,
cat: cat_deref(Rc::new(cmt_result), 0, env_ptr),
cat: Categorization::Deref(Rc::new(cmt_result), 0, env_ptr),
mutbl: deref_mutbl,
ty: var_ty,
note: NoteClosureEnv(upvar_id)
@ -825,7 +824,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
let ret = Rc::new(cmt_ {
id:cmt_id,
span:span,
cat:cat_rvalue(temp_scope),
cat:Categorization::Rvalue(temp_scope),
mutbl:McDeclared,
ty:expr_ty,
note: NoteNone
@ -844,7 +843,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
id: node.id(),
span: node.span(),
mutbl: base_cmt.mutbl.inherit(),
cat: cat_interior(base_cmt, InteriorField(NamedField(f_name))),
cat: Categorization::Interior(base_cmt, InteriorField(NamedField(f_name))),
ty: f_ty,
note: NoteNone
});
@ -862,7 +861,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
id: node.id(),
span: node.span(),
mutbl: base_cmt.mutbl.inherit(),
cat: cat_interior(base_cmt, InteriorField(PositionalField(f_idx))),
cat: Categorization::Interior(base_cmt, InteriorField(PositionalField(f_idx))),
ty: f_ty,
note: NoteNone
});
@ -934,10 +933,10 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
// for unique ptrs, we inherit mutability from the
// owning reference.
(MutabilityCategory::from_pointer_kind(base_cmt.mutbl, ptr),
cat_deref(base_cmt, deref_cnt, ptr))
Categorization::Deref(base_cmt, deref_cnt, ptr))
}
deref_interior(interior) => {
(base_cmt.mutbl.inherit(), cat_interior(base_cmt, interior))
(base_cmt.mutbl.inherit(), Categorization::Interior(base_cmt, interior))
}
};
let ret = Rc::new(cmt_ {
@ -1013,7 +1012,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
Rc::new(cmt_ {
id:elt.id(),
span:elt.span(),
cat:cat_interior(of_cmt, interior_elem),
cat:Categorization::Interior(of_cmt, interior_elem),
mutbl:mutbl,
ty:element_ty,
note: NoteNone
@ -1039,7 +1038,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
Rc::new(cmt_ {
id:elt.id(),
span:elt.span(),
cat:cat_deref(base_cmt.clone(), 0, ptr),
cat:Categorization::Deref(base_cmt.clone(), 0, ptr),
mutbl:m,
ty: match base_cmt.ty.builtin_deref(false, ty::NoPreference) {
Some(mt) => mt.ty,
@ -1108,7 +1107,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
id: node.id(),
span: node.span(),
mutbl: base_cmt.mutbl.inherit(),
cat: cat_interior(base_cmt, interior),
cat: Categorization::Interior(base_cmt, interior),
ty: interior_ty,
note: NoteNone
});
@ -1126,7 +1125,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
id: node.id(),
span: node.span(),
mutbl: base_cmt.mutbl.inherit(),
cat: cat_downcast(base_cmt, variant_did),
cat: Categorization::Downcast(base_cmt, variant_did),
ty: downcast_ty,
note: NoteNone
});
@ -1361,18 +1360,18 @@ impl<'tcx> cmt_<'tcx> {
//! determines how long the value in `self` remains live.
match self.cat {
cat_rvalue(..) |
cat_static_item |
cat_local(..) |
cat_deref(_, _, UnsafePtr(..)) |
cat_deref(_, _, BorrowedPtr(..)) |
cat_deref(_, _, Implicit(..)) |
cat_upvar(..) => {
Categorization::Rvalue(..) |
Categorization::StaticItem |
Categorization::Local(..) |
Categorization::Deref(_, _, UnsafePtr(..)) |
Categorization::Deref(_, _, BorrowedPtr(..)) |
Categorization::Deref(_, _, Implicit(..)) |
Categorization::Upvar(..) => {
Rc::new((*self).clone())
}
cat_downcast(ref b, _) |
cat_interior(ref b, _) |
cat_deref(ref b, _, Unique) => {
Categorization::Downcast(ref b, _) |
Categorization::Interior(ref b, _) |
Categorization::Deref(ref b, _, Unique) => {
b.guarantor()
}
}
@ -1386,17 +1385,17 @@ impl<'tcx> cmt_<'tcx> {
// aliased and eventually recused.
match self.cat {
cat_deref(ref b, _, BorrowedPtr(ty::MutBorrow, _)) |
cat_deref(ref b, _, Implicit(ty::MutBorrow, _)) |
cat_deref(ref b, _, BorrowedPtr(ty::UniqueImmBorrow, _)) |
cat_deref(ref b, _, Implicit(ty::UniqueImmBorrow, _)) |
cat_downcast(ref b, _) |
cat_interior(ref b, _) => {
Categorization::Deref(ref b, _, BorrowedPtr(ty::MutBorrow, _)) |
Categorization::Deref(ref b, _, Implicit(ty::MutBorrow, _)) |
Categorization::Deref(ref b, _, BorrowedPtr(ty::UniqueImmBorrow, _)) |
Categorization::Deref(ref b, _, Implicit(ty::UniqueImmBorrow, _)) |
Categorization::Downcast(ref b, _) |
Categorization::Interior(ref b, _) => {
// Aliasability depends on base cmt
b.freely_aliasable(ctxt)
}
cat_deref(ref b, _, Unique) => {
Categorization::Deref(ref b, _, Unique) => {
let sub = b.freely_aliasable(ctxt);
if b.mutbl.is_mutable() {
// Aliasability depends on base cmt alone
@ -1407,14 +1406,14 @@ impl<'tcx> cmt_<'tcx> {
}
}
cat_rvalue(..) |
cat_local(..) |
cat_upvar(..) |
cat_deref(_, _, UnsafePtr(..)) => { // yes, it's aliasable, but...
Categorization::Rvalue(..) |
Categorization::Local(..) |
Categorization::Upvar(..) |
Categorization::Deref(_, _, UnsafePtr(..)) => { // yes, it's aliasable, but...
NonAliasable
}
cat_static_item(..) => {
Categorization::StaticItem(..) => {
if self.mutbl.is_mutable() {
FreelyAliasable(AliasableStaticMut)
} else {
@ -1422,10 +1421,10 @@ impl<'tcx> cmt_<'tcx> {
}
}
cat_deref(ref base, _, BorrowedPtr(ty::ImmBorrow, _)) |
cat_deref(ref base, _, Implicit(ty::ImmBorrow, _)) => {
Categorization::Deref(ref base, _, BorrowedPtr(ty::ImmBorrow, _)) |
Categorization::Deref(ref base, _, Implicit(ty::ImmBorrow, _)) => {
match base.cat {
cat_upvar(Upvar{ id, .. }) =>
Categorization::Upvar(Upvar{ id, .. }) =>
FreelyAliasable(AliasableClosure(id.closure_expr_id)),
_ => FreelyAliasable(AliasableBorrowed)
}
@ -1439,10 +1438,10 @@ impl<'tcx> cmt_<'tcx> {
match self.note {
NoteClosureEnv(..) | NoteUpvarRef(..) => {
Some(match self.cat {
cat_deref(ref inner, _, _) => {
Categorization::Deref(ref inner, _, _) => {
match inner.cat {
cat_deref(ref inner, _, _) => inner.clone(),
cat_upvar(..) => inner.clone(),
Categorization::Deref(ref inner, _, _) => inner.clone(),
Categorization::Upvar(..) => inner.clone(),
_ => unreachable!()
}
}
@ -1456,23 +1455,23 @@ impl<'tcx> cmt_<'tcx> {
pub fn descriptive_string(&self, tcx: &ty::ctxt) -> String {
match self.cat {
cat_static_item => {
Categorization::StaticItem => {
"static item".to_string()
}
cat_rvalue(..) => {
Categorization::Rvalue(..) => {
"non-lvalue".to_string()
}
cat_local(vid) => {
Categorization::Local(vid) => {
if tcx.map.is_argument(vid) {
"argument".to_string()
} else {
"local variable".to_string()
}
}
cat_deref(_, _, pk) => {
Categorization::Deref(_, _, pk) => {
let upvar = self.upvar();
match upvar.as_ref().map(|i| &i.cat) {
Some(&cat_upvar(ref var)) => {
Some(&Categorization::Upvar(ref var)) => {
var.to_string()
}
Some(_) => unreachable!(),
@ -1494,28 +1493,28 @@ impl<'tcx> cmt_<'tcx> {
}
}
}
cat_interior(_, InteriorField(NamedField(_))) => {
Categorization::Interior(_, InteriorField(NamedField(_))) => {
"field".to_string()
}
cat_interior(_, InteriorField(PositionalField(_))) => {
Categorization::Interior(_, InteriorField(PositionalField(_))) => {
"anonymous field".to_string()
}
cat_interior(_, InteriorElement(InteriorOffsetKind::Index,
VecElement)) |
cat_interior(_, InteriorElement(InteriorOffsetKind::Index,
OtherElement)) => {
Categorization::Interior(_, InteriorElement(InteriorOffsetKind::Index,
VecElement)) |
Categorization::Interior(_, InteriorElement(InteriorOffsetKind::Index,
OtherElement)) => {
"indexed content".to_string()
}
cat_interior(_, InteriorElement(InteriorOffsetKind::Pattern,
VecElement)) |
cat_interior(_, InteriorElement(InteriorOffsetKind::Pattern,
OtherElement)) => {
Categorization::Interior(_, InteriorElement(InteriorOffsetKind::Pattern,
VecElement)) |
Categorization::Interior(_, InteriorElement(InteriorOffsetKind::Pattern,
OtherElement)) => {
"pattern-bound indexed content".to_string()
}
cat_upvar(ref var) => {
Categorization::Upvar(ref var) => {
var.to_string()
}
cat_downcast(ref cmt, _) => {
Categorization::Downcast(ref cmt, _) => {
cmt.descriptive_string(tcx)
}
}
@ -1532,25 +1531,25 @@ impl<'tcx> fmt::Debug for cmt_<'tcx> {
}
}
impl<'tcx> fmt::Debug for categorization<'tcx> {
impl<'tcx> fmt::Debug for Categorization<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
cat_static_item => write!(f, "static"),
cat_rvalue(r) => write!(f, "rvalue({:?})", r),
cat_local(id) => {
Categorization::StaticItem => write!(f, "static"),
Categorization::Rvalue(r) => write!(f, "rvalue({:?})", r),
Categorization::Local(id) => {
let name = ty::tls::with(|tcx| tcx.local_var_name_str(id));
write!(f, "local({})", name)
}
cat_upvar(upvar) => {
Categorization::Upvar(upvar) => {
write!(f, "upvar({:?})", upvar)
}
cat_deref(ref cmt, derefs, ptr) => {
Categorization::Deref(ref cmt, derefs, ptr) => {
write!(f, "{:?}-{:?}{}->", cmt.cat, ptr, derefs)
}
cat_interior(ref cmt, interior) => {
Categorization::Interior(ref cmt, interior) => {
write!(f, "{:?}.{:?}", cmt.cat, interior)
}
cat_downcast(ref cmt, _) => {
Categorization::Downcast(ref cmt, _) => {
write!(f, "{:?}->(enum)", cmt.cat)
}
}

View File

@ -23,6 +23,7 @@ use borrowck::InteriorKind::{InteriorElement, InteriorField};
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::infer;
use rustc::middle::mem_categorization as mc;
use rustc::middle::mem_categorization::Categorization;
use rustc::middle::region;
use rustc::middle::ty;
use syntax::ast;
@ -796,7 +797,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
// Check for reassignments to (immutable) local variables. This
// needs to be done here instead of in check_loans because we
// depend on move data.
if let mc::cat_local(local_id) = assignee_cmt.cat {
if let Categorization::Local(local_id) = assignee_cmt.cat {
let lp = opt_loan_path(&assignee_cmt).unwrap();
self.move_data.each_assignment_of(assignment_id, &lp, |assign| {
if assignee_cmt.mutbl.is_mutable() {

View File

@ -16,6 +16,7 @@ use borrowck::gather_loans::move_error::{MoveError, MoveErrorCollector};
use borrowck::move_data::*;
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::mem_categorization as mc;
use rustc::middle::mem_categorization::Categorization;
use rustc::middle::mem_categorization::InteriorOffsetKind as Kind;
use rustc::middle::ty;
@ -163,22 +164,22 @@ fn check_and_get_illegal_move_origin<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
cmt: &mc::cmt<'tcx>)
-> Option<mc::cmt<'tcx>> {
match cmt.cat {
mc::cat_deref(_, _, mc::BorrowedPtr(..)) |
mc::cat_deref(_, _, mc::Implicit(..)) |
mc::cat_deref(_, _, mc::UnsafePtr(..)) |
mc::cat_static_item => {
Categorization::Deref(_, _, mc::BorrowedPtr(..)) |
Categorization::Deref(_, _, mc::Implicit(..)) |
Categorization::Deref(_, _, mc::UnsafePtr(..)) |
Categorization::StaticItem => {
Some(cmt.clone())
}
mc::cat_rvalue(..) |
mc::cat_local(..) |
mc::cat_upvar(..) => {
Categorization::Rvalue(..) |
Categorization::Local(..) |
Categorization::Upvar(..) => {
None
}
mc::cat_downcast(ref b, _) |
mc::cat_interior(ref b, mc::InteriorField(_)) |
mc::cat_interior(ref b, mc::InteriorElement(Kind::Pattern, _)) => {
Categorization::Downcast(ref b, _) |
Categorization::Interior(ref b, mc::InteriorField(_)) |
Categorization::Interior(ref b, mc::InteriorElement(Kind::Pattern, _)) => {
match b.ty.sty {
ty::TyStruct(def, _) | ty::TyEnum(def, _) => {
if def.has_dtor() {
@ -193,12 +194,12 @@ fn check_and_get_illegal_move_origin<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
}
}
mc::cat_interior(_, mc::InteriorElement(Kind::Index, _)) => {
Categorization::Interior(_, mc::InteriorElement(Kind::Index, _)) => {
// Forbid move of arr[i] for arr: [T; 3]; see RFC 533.
Some(cmt.clone())
}
mc::cat_deref(ref b, _, mc::Unique) => {
Categorization::Deref(ref b, _, mc::Unique) => {
check_and_get_illegal_move_origin(bccx, b)
}
}

View File

@ -14,6 +14,7 @@
use borrowck::*;
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::mem_categorization as mc;
use rustc::middle::mem_categorization::Categorization;
use rustc::middle::region;
use rustc::middle::ty;
@ -70,22 +71,22 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
self.loan_region);
match cmt.cat {
mc::cat_rvalue(..) |
mc::cat_local(..) | // L-Local
mc::cat_upvar(..) |
mc::cat_deref(_, _, mc::BorrowedPtr(..)) | // L-Deref-Borrowed
mc::cat_deref(_, _, mc::Implicit(..)) |
mc::cat_deref(_, _, mc::UnsafePtr(..)) => {
Categorization::Rvalue(..) |
Categorization::Local(..) | // L-Local
Categorization::Upvar(..) |
Categorization::Deref(_, _, mc::BorrowedPtr(..)) | // L-Deref-Borrowed
Categorization::Deref(_, _, mc::Implicit(..)) |
Categorization::Deref(_, _, mc::UnsafePtr(..)) => {
self.check_scope(self.scope(cmt))
}
mc::cat_static_item => {
Categorization::StaticItem => {
Ok(())
}
mc::cat_downcast(ref base, _) |
mc::cat_deref(ref base, _, mc::Unique) | // L-Deref-Send
mc::cat_interior(ref base, _) => { // L-Field
Categorization::Downcast(ref base, _) |
Categorization::Deref(ref base, _, mc::Unique) | // L-Deref-Send
Categorization::Interior(ref base, _) => { // L-Field
self.check(base, discr_scope)
}
}
@ -107,28 +108,28 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
//! rooting etc, and presuming `cmt` is not mutated.
match cmt.cat {
mc::cat_rvalue(temp_scope) => {
Categorization::Rvalue(temp_scope) => {
temp_scope
}
mc::cat_upvar(..) => {
Categorization::Upvar(..) => {
ty::ReScope(self.item_scope)
}
mc::cat_static_item => {
Categorization::StaticItem => {
ty::ReStatic
}
mc::cat_local(local_id) => {
Categorization::Local(local_id) => {
ty::ReScope(self.bccx.tcx.region_maps.var_scope(local_id))
}
mc::cat_deref(_, _, mc::UnsafePtr(..)) => {
Categorization::Deref(_, _, mc::UnsafePtr(..)) => {
ty::ReStatic
}
mc::cat_deref(_, _, mc::BorrowedPtr(_, r)) |
mc::cat_deref(_, _, mc::Implicit(_, r)) => {
Categorization::Deref(_, _, mc::BorrowedPtr(_, r)) |
Categorization::Deref(_, _, mc::Implicit(_, r)) => {
r
}
mc::cat_downcast(ref cmt, _) |
mc::cat_deref(ref cmt, _, mc::Unique) |
mc::cat_interior(ref cmt, _) => {
Categorization::Downcast(ref cmt, _) |
Categorization::Deref(ref cmt, _, mc::Unique) |
Categorization::Interior(ref cmt, _) => {
self.scope(cmt)
}
}

View File

@ -21,6 +21,7 @@ use borrowck::move_data::MoveData;
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::infer;
use rustc::middle::mem_categorization as mc;
use rustc::middle::mem_categorization::Categorization;
use rustc::middle::region;
use rustc::middle::ty;
@ -101,7 +102,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> {
cmt,
mode);
if let mc::cat_downcast(..) = cmt.cat {
if let Categorization::Downcast(..) = cmt.cat {
gather_moves::gather_match_variant(
self.bccx, &self.move_data, &self.move_error_collector,
matched_pat, cmt, mode);
@ -263,7 +264,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
debug!("guarantee_assignment_valid(assignment_id={}, cmt={:?}) opt_lp={:?}",
assignment_id, cmt, opt_lp);
if let mc::cat_local(..) = cmt.cat {
if let Categorization::Local(..) = cmt.cat {
// Only re-assignments to locals require it to be
// mutable - this is checked in check_loans.
} else {
@ -282,7 +283,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
match opt_lp {
Some(lp) => {
if let mc::cat_local(..) = cmt.cat {
if let Categorization::Local(..) = cmt.cat {
// Only re-assignments to locals require it to be
// mutable - this is checked in check_loans.
} else {

View File

@ -10,6 +10,7 @@
use borrowck::BorrowckCtxt;
use rustc::middle::mem_categorization as mc;
use rustc::middle::mem_categorization::Categorization;
use rustc::middle::mem_categorization::InteriorOffsetKind as Kind;
use rustc::middle::ty;
use std::cell::RefCell;
@ -114,16 +115,16 @@ fn group_errors_with_same_origin<'tcx>(errors: &Vec<MoveError<'tcx>>)
fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
move_from: mc::cmt<'tcx>) {
match move_from.cat {
mc::cat_deref(_, _, mc::BorrowedPtr(..)) |
mc::cat_deref(_, _, mc::Implicit(..)) |
mc::cat_deref(_, _, mc::UnsafePtr(..)) |
mc::cat_static_item => {
Categorization::Deref(_, _, mc::BorrowedPtr(..)) |
Categorization::Deref(_, _, mc::Implicit(..)) |
Categorization::Deref(_, _, mc::UnsafePtr(..)) |
Categorization::StaticItem => {
span_err!(bccx, move_from.span, E0507,
"cannot move out of {}",
move_from.descriptive_string(bccx.tcx));
}
mc::cat_interior(ref b, mc::InteriorElement(Kind::Index, _)) => {
Categorization::Interior(ref b, mc::InteriorElement(Kind::Index, _)) => {
let expr = bccx.tcx.map.expect_expr(move_from.id);
if let hir::ExprIndex(..) = expr.node {
span_err!(bccx, move_from.span, E0508,
@ -133,8 +134,8 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
}
}
mc::cat_downcast(ref b, _) |
mc::cat_interior(ref b, mc::InteriorField(_)) => {
Categorization::Downcast(ref b, _) |
Categorization::Interior(ref b, mc::InteriorField(_)) => {
match b.ty.sty {
ty::TyStruct(def, _) |
ty::TyEnum(def, _) if def.has_dtor() => {

View File

@ -15,6 +15,7 @@ pub use self::RestrictionResult::*;
use borrowck::*;
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::mem_categorization as mc;
use rustc::middle::mem_categorization::Categorization;
use rustc::middle::ty;
use syntax::codemap::Span;
@ -62,7 +63,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
let new_lp = |v: LoanPathKind<'tcx>| Rc::new(LoanPath::new(v, cmt.ty));
match cmt.cat.clone() {
mc::cat_rvalue(..) => {
Categorization::Rvalue(..) => {
// Effectively, rvalues are stored into a
// non-aliasable temporary on the stack. Since they
// are inherently non-aliasable, they can only be
@ -71,26 +72,26 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
Safe
}
mc::cat_local(local_id) => {
Categorization::Local(local_id) => {
// R-Variable, locally declared
let lp = new_lp(LpVar(local_id));
SafeIf(lp.clone(), vec![lp])
}
mc::cat_upvar(mc::Upvar { id, .. }) => {
Categorization::Upvar(mc::Upvar { id, .. }) => {
// R-Variable, captured into closure
let lp = new_lp(LpUpvar(id));
SafeIf(lp.clone(), vec![lp])
}
mc::cat_downcast(cmt_base, _) => {
Categorization::Downcast(cmt_base, _) => {
// 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)
}
mc::cat_interior(cmt_base, i) => {
Categorization::Interior(cmt_base, i) => {
// R-Field
//
// Overwriting the base would not change the type of
@ -100,11 +101,11 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
self.extend(result, &cmt, LpInterior(i.cleaned()))
}
mc::cat_static_item(..) => {
Categorization::StaticItem(..) => {
Safe
}
mc::cat_deref(cmt_base, _, pk) => {
Categorization::Deref(cmt_base, _, pk) => {
match pk {
mc::Unique => {
// R-Deref-Send-Pointer

View File

@ -31,6 +31,7 @@ use rustc::middle::def_id::DefId;
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::free_region::FreeRegionMap;
use rustc::middle::mem_categorization as mc;
use rustc::middle::mem_categorization::Categorization;
use rustc::middle::region;
use rustc::middle::ty::{self, Ty};
@ -502,32 +503,32 @@ pub fn opt_loan_path<'tcx>(cmt: &mc::cmt<'tcx>) -> Option<Rc<LoanPath<'tcx>>> {
let new_lp = |v: LoanPathKind<'tcx>| Rc::new(LoanPath::new(v, cmt.ty));
match cmt.cat {
mc::cat_rvalue(..) |
mc::cat_static_item => {
Categorization::Rvalue(..) |
Categorization::StaticItem => {
None
}
mc::cat_local(id) => {
Categorization::Local(id) => {
Some(new_lp(LpVar(id)))
}
mc::cat_upvar(mc::Upvar { id, .. }) => {
Categorization::Upvar(mc::Upvar { id, .. }) => {
Some(new_lp(LpUpvar(id)))
}
mc::cat_deref(ref cmt_base, _, pk) => {
Categorization::Deref(ref cmt_base, _, pk) => {
opt_loan_path(cmt_base).map(|lp| {
new_lp(LpExtend(lp, cmt.mutbl, LpDeref(pk)))
})
}
mc::cat_interior(ref cmt_base, ik) => {
Categorization::Interior(ref cmt_base, ik) => {
opt_loan_path(cmt_base).map(|lp| {
new_lp(LpExtend(lp, cmt.mutbl, LpInterior(ik.cleaned())))
})
}
mc::cat_downcast(ref cmt_base, variant_def_id) =>
Categorization::Downcast(ref cmt_base, variant_def_id) =>
opt_loan_path(cmt_base)
.map(|lp| {
new_lp(LpDowncast(lp, variant_def_id))
@ -1004,7 +1005,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
// 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 {
mc::cat_upvar(mc::Upvar { kind, .. }) => kind,
Categorization::Upvar(mc::Upvar { kind, .. }) => kind,
_ => unreachable!()
};
if kind == ty::FnClosureKind {

View File

@ -198,6 +198,7 @@ use middle::expr_use_visitor as euv;
use middle::infer;
use middle::lang_items::StrEqFnLangItem;
use middle::mem_categorization as mc;
use middle::mem_categorization::Categorization;
use middle::pat_util::*;
use trans::adt;
use trans::base::*;
@ -1496,12 +1497,12 @@ impl<'tcx> euv::Delegate<'tcx> for ReassignmentChecker {
fn mutate(&mut self, _: ast::NodeId, _: Span, cmt: mc::cmt, _: euv::MutateMode) {
match cmt.cat {
mc::cat_upvar(mc::Upvar { id: ty::UpvarId { var_id: vid, .. }, .. }) |
mc::cat_local(vid) => self.reassigned |= self.node == vid,
mc::cat_interior(ref base_cmt, mc::InteriorField(field)) => {
Categorization::Upvar(mc::Upvar { id: ty::UpvarId { var_id: vid, .. }, .. }) |
Categorization::Local(vid) => self.reassigned |= self.node == vid,
Categorization::Interior(ref base_cmt, mc::InteriorField(field)) => {
match base_cmt.cat {
mc::cat_upvar(mc::Upvar { id: ty::UpvarId { var_id: vid, .. }, .. }) |
mc::cat_local(vid) => {
Categorization::Upvar(mc::Upvar { id: ty::UpvarId { var_id: vid, .. }, .. }) |
Categorization::Local(vid) => {
self.reassigned |= self.node == vid &&
(self.field.is_none() || Some(field) == self.field)
},

View File

@ -88,6 +88,7 @@ use check::FnCtxt;
use middle::free_region::FreeRegionMap;
use middle::implicator::{self, Implication};
use middle::mem_categorization as mc;
use middle::mem_categorization::Categorization;
use middle::region::CodeExtent;
use middle::subst::Substs;
use middle::traits;
@ -1058,7 +1059,7 @@ fn check_safety_of_rvalue_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 't
cmt: mc::cmt<'tcx>,
span: Span) {
match cmt.cat {
mc::cat_rvalue(region) => {
Categorization::Rvalue(region) => {
match region {
ty::ReScope(rvalue_scope) => {
let typ = rcx.resolve_type(cmt.ty);
@ -1300,10 +1301,10 @@ fn link_region<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
borrow_kind,
borrow_cmt);
match borrow_cmt.cat.clone() {
mc::cat_deref(ref_cmt, _,
mc::Implicit(ref_kind, ref_region)) |
mc::cat_deref(ref_cmt, _,
mc::BorrowedPtr(ref_kind, ref_region)) => {
Categorization::Deref(ref_cmt, _,
mc::Implicit(ref_kind, ref_region)) |
Categorization::Deref(ref_cmt, _,
mc::BorrowedPtr(ref_kind, ref_region)) => {
match link_reborrowed_region(rcx, span,
borrow_region, borrow_kind,
ref_cmt, ref_region, ref_kind,
@ -1318,20 +1319,20 @@ fn link_region<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
}
}
mc::cat_downcast(cmt_base, _) |
mc::cat_deref(cmt_base, _, mc::Unique) |
mc::cat_interior(cmt_base, _) => {
Categorization::Downcast(cmt_base, _) |
Categorization::Deref(cmt_base, _, mc::Unique) |
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_kind = borrow_kind;
}
mc::cat_deref(_, _, mc::UnsafePtr(..)) |
mc::cat_static_item |
mc::cat_upvar(..) |
mc::cat_local(..) |
mc::cat_rvalue(..) => {
Categorization::Deref(_, _, mc::UnsafePtr(..)) |
Categorization::StaticItem |
Categorization::Upvar(..) |
Categorization::Local(..) |
Categorization::Rvalue(..) => {
// These are all "base cases" with independent lifetimes
// that are not subject to inference
return;

View File

@ -45,6 +45,7 @@ use super::FnCtxt;
use check::demand;
use middle::expr_use_visitor as euv;
use middle::mem_categorization as mc;
use middle::mem_categorization::Categorization;
use middle::ty::{self, Ty};
use middle::infer::{InferCtxt, UpvarRegion};
use std::collections::HashSet;
@ -294,8 +295,8 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
debug!("adjust_upvar_borrow_kind_for_consume: guarantor={:?}",
guarantor);
match guarantor.cat {
mc::cat_deref(_, _, mc::BorrowedPtr(..)) |
mc::cat_deref(_, _, mc::Implicit(..)) => {
Categorization::Deref(_, _, mc::BorrowedPtr(..)) |
Categorization::Deref(_, _, mc::Implicit(..)) => {
match cmt.note {
mc::NoteUpvarRef(upvar_id) => {
debug!("adjust_upvar_borrow_kind_for_consume: \
@ -334,16 +335,16 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
cmt);
match cmt.cat.clone() {
mc::cat_deref(base, _, mc::Unique) |
mc::cat_interior(base, _) |
mc::cat_downcast(base, _) => {
Categorization::Deref(base, _, mc::Unique) |
Categorization::Interior(base, _) |
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);
}
mc::cat_deref(base, _, mc::BorrowedPtr(..)) |
mc::cat_deref(base, _, mc::Implicit(..)) => {
Categorization::Deref(base, _, mc::BorrowedPtr(..)) |
Categorization::Deref(base, _, mc::Implicit(..)) => {
if !self.try_adjust_upvar_deref(&cmt.note, ty::MutBorrow) {
// assignment to deref of an `&mut`
// borrowed pointer implies that the
@ -353,11 +354,11 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
}
}
mc::cat_deref(_, _, mc::UnsafePtr(..)) |
mc::cat_static_item |
mc::cat_rvalue(_) |
mc::cat_local(_) |
mc::cat_upvar(..) => {
Categorization::Deref(_, _, mc::UnsafePtr(..)) |
Categorization::StaticItem |
Categorization::Rvalue(_) |
Categorization::Local(_) |
Categorization::Upvar(..) => {
return;
}
}
@ -368,16 +369,16 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
cmt);
match cmt.cat.clone() {
mc::cat_deref(base, _, mc::Unique) |
mc::cat_interior(base, _) |
mc::cat_downcast(base, _) => {
Categorization::Deref(base, _, mc::Unique) |
Categorization::Interior(base, _) |
Categorization::Downcast(base, _) => {
// Interior or owned data is unique if base is
// unique.
self.adjust_upvar_borrow_kind_for_unique(base);
}
mc::cat_deref(base, _, mc::BorrowedPtr(..)) |
mc::cat_deref(base, _, mc::Implicit(..)) => {
Categorization::Deref(base, _, mc::BorrowedPtr(..)) |
Categorization::Deref(base, _, mc::Implicit(..)) => {
if !self.try_adjust_upvar_deref(&cmt.note, ty::UniqueImmBorrow) {
// for a borrowed pointer to be unique, its
// base must be unique
@ -385,11 +386,11 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
}
}
mc::cat_deref(_, _, mc::UnsafePtr(..)) |
mc::cat_static_item |
mc::cat_rvalue(_) |
mc::cat_local(_) |
mc::cat_upvar(..) => {
Categorization::Deref(_, _, mc::UnsafePtr(..)) |
Categorization::StaticItem |
Categorization::Rvalue(_) |
Categorization::Local(_) |
Categorization::Upvar(..) => {
}
}
}