mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-29 20:46:07 +03:00
borrowck: Integrate AutoBorrowObj into borrowck / mem_categorization
Also cleanup the treatment of mutability in mem_categorization, which still included the concept of interior mutability. At some point, we should refactor the types to exclude the possibility of interior mutability rather than just ignoring the mutability value in those cases.
This commit is contained in:
@@ -362,7 +362,7 @@ fn mark_variable_as_used_mut(this: &CheckLoanCtxt,
|
||||
}
|
||||
|
||||
mc::cat_discr(b, _) |
|
||||
mc::cat_deref(b, _, mc::uniq_ptr(*)) => {
|
||||
mc::cat_deref(b, _, mc::uniq_ptr) => {
|
||||
assert_eq!(cmt.mutbl, mc::McInherited);
|
||||
cmt = b;
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ fn check_is_legal_to_move_from(bccx: @BorrowckCtxt,
|
||||
}
|
||||
}
|
||||
|
||||
mc::cat_deref(b, _, mc::uniq_ptr(*)) |
|
||||
mc::cat_deref(b, _, mc::uniq_ptr) |
|
||||
mc::cat_discr(b, _) => {
|
||||
check_is_legal_to_move_from(bccx, cmt0, b)
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ fn check(&self, cmt: mc::cmt, discr_scope: Option<ast::NodeId>) {
|
||||
mc::cat_arg(*) | // L-Local
|
||||
mc::cat_self(*) | // L-Local
|
||||
mc::cat_deref(_, _, mc::region_ptr(*)) | // L-Deref-Borrowed
|
||||
mc::cat_deref(_, _, mc::unsafe_ptr) => {
|
||||
mc::cat_deref(_, _, mc::unsafe_ptr(*)) => {
|
||||
let scope = self.scope(cmt);
|
||||
self.check_scope(scope)
|
||||
}
|
||||
@@ -108,7 +108,7 @@ fn check(&self, cmt: mc::cmt, discr_scope: Option<ast::NodeId>) {
|
||||
}
|
||||
|
||||
mc::cat_downcast(base) |
|
||||
mc::cat_deref(base, _, mc::uniq_ptr(*)) | // L-Deref-Send
|
||||
mc::cat_deref(base, _, mc::uniq_ptr) | // L-Deref-Send
|
||||
mc::cat_interior(base, _) => { // L-Field
|
||||
self.check(base, discr_scope)
|
||||
}
|
||||
@@ -347,7 +347,7 @@ fn scope(&self, cmt: mc::cmt) -> ty::Region {
|
||||
r
|
||||
}
|
||||
mc::cat_downcast(cmt) |
|
||||
mc::cat_deref(cmt, _, mc::uniq_ptr(*)) |
|
||||
mc::cat_deref(cmt, _, mc::uniq_ptr) |
|
||||
mc::cat_deref(cmt, _, mc::gc_ptr(*)) |
|
||||
mc::cat_interior(cmt, _) |
|
||||
mc::cat_stack_upvar(cmt) |
|
||||
|
||||
@@ -352,13 +352,21 @@ pub fn guarantee_adjustments(&mut self,
|
||||
r)
|
||||
}
|
||||
ty::AutoBorrowFn(r) => {
|
||||
let cmt_deref = mcx.cat_deref_fn(expr, cmt, 0);
|
||||
let cmt_deref = mcx.cat_deref_fn_or_obj(expr, cmt, 0);
|
||||
self.guarantee_valid(expr.id,
|
||||
expr.span,
|
||||
cmt_deref,
|
||||
m_imm,
|
||||
r)
|
||||
}
|
||||
ty::AutoBorrowObj(r, m) => {
|
||||
let cmt_deref = mcx.cat_deref_fn_or_obj(expr, cmt, 0);
|
||||
self.guarantee_valid(expr.id,
|
||||
expr.span,
|
||||
cmt_deref,
|
||||
m,
|
||||
r)
|
||||
}
|
||||
ty::AutoUnsafe(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ fn restrict(&self,
|
||||
self.extend(result, cmt.mutbl, LpInterior(i), restrictions)
|
||||
}
|
||||
|
||||
mc::cat_deref(cmt_base, _, mc::uniq_ptr(*)) => {
|
||||
mc::cat_deref(cmt_base, _, mc::uniq_ptr) => {
|
||||
// R-Deref-Send-Pointer
|
||||
//
|
||||
// When we borrow the interior of an owned pointer, we
|
||||
@@ -194,7 +194,7 @@ fn restrict(&self,
|
||||
}
|
||||
}
|
||||
|
||||
mc::cat_deref(_, _, mc::unsafe_ptr) => {
|
||||
mc::cat_deref(_, _, mc::unsafe_ptr(*)) => {
|
||||
// We are very trusting when working with unsafe pointers.
|
||||
Safe
|
||||
}
|
||||
|
||||
@@ -84,10 +84,10 @@ pub struct CopiedUpvar {
|
||||
// different kinds of pointers:
|
||||
#[deriving(Eq)]
|
||||
pub enum ptr_kind {
|
||||
uniq_ptr(ast::mutability),
|
||||
uniq_ptr,
|
||||
gc_ptr(ast::mutability),
|
||||
region_ptr(ast::mutability, ty::Region),
|
||||
unsafe_ptr
|
||||
unsafe_ptr(ast::mutability)
|
||||
}
|
||||
|
||||
// We use the term "interior" to mean "something reachable from the
|
||||
@@ -156,14 +156,12 @@ pub enum deref_kind {
|
||||
// pointer adjustment).
|
||||
pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
|
||||
match ty::get(t).sty {
|
||||
ty::ty_uniq(mt) => {
|
||||
Some(deref_ptr(uniq_ptr(mt.mutbl)))
|
||||
}
|
||||
|
||||
ty::ty_uniq(_) |
|
||||
ty::ty_trait(_, _, ty::UniqTraitStore, _, _) |
|
||||
ty::ty_evec(_, ty::vstore_uniq) |
|
||||
ty::ty_estr(ty::vstore_uniq) |
|
||||
ty::ty_closure(ty::ClosureTy {sigil: ast::OwnedSigil, _}) => {
|
||||
Some(deref_ptr(uniq_ptr(m_imm)))
|
||||
Some(deref_ptr(uniq_ptr))
|
||||
}
|
||||
|
||||
ty::ty_rptr(r, mt) |
|
||||
@@ -171,24 +169,32 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
|
||||
Some(deref_ptr(region_ptr(mt.mutbl, r)))
|
||||
}
|
||||
|
||||
ty::ty_trait(_, _, ty::RegionTraitStore(r), m, _) => {
|
||||
Some(deref_ptr(region_ptr(m, r)))
|
||||
}
|
||||
|
||||
ty::ty_estr(ty::vstore_slice(r)) |
|
||||
ty::ty_closure(ty::ClosureTy {sigil: ast::BorrowedSigil,
|
||||
region: r, _}) => {
|
||||
Some(deref_ptr(region_ptr(ast::m_imm, r)))
|
||||
}
|
||||
|
||||
ty::ty_box(mt) |
|
||||
ty::ty_evec(mt, ty::vstore_box) => {
|
||||
ty::ty_box(ref mt) |
|
||||
ty::ty_evec(ref mt, ty::vstore_box) => {
|
||||
Some(deref_ptr(gc_ptr(mt.mutbl)))
|
||||
}
|
||||
|
||||
ty::ty_trait(_, _, ty::BoxTraitStore, m, _) => {
|
||||
Some(deref_ptr(gc_ptr(m)))
|
||||
}
|
||||
|
||||
ty::ty_estr(ty::vstore_box) |
|
||||
ty::ty_closure(ty::ClosureTy {sigil: ast::ManagedSigil, _}) => {
|
||||
Some(deref_ptr(gc_ptr(ast::m_imm)))
|
||||
}
|
||||
|
||||
ty::ty_ptr(*) => {
|
||||
Some(deref_ptr(unsafe_ptr))
|
||||
ty::ty_ptr(ref mt) => {
|
||||
Some(deref_ptr(unsafe_ptr(mt.mutbl)))
|
||||
}
|
||||
|
||||
ty::ty_enum(*) |
|
||||
@@ -631,20 +637,19 @@ pub fn cat_field<N:ast_node>(&self,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cat_deref_fn<N:ast_node>(&self,
|
||||
node: N,
|
||||
base_cmt: cmt,
|
||||
deref_cnt: uint)
|
||||
-> cmt {
|
||||
pub fn cat_deref_fn_or_obj<N:ast_node>(&self,
|
||||
node: N,
|
||||
base_cmt: cmt,
|
||||
deref_cnt: uint)
|
||||
-> cmt {
|
||||
// Bit of a hack: the "dereference" of a function pointer like
|
||||
// `@fn()` is a mere logical concept. We interpret it as
|
||||
// dereferencing the environment pointer; of course, we don't
|
||||
// know what type lies at the other end, so we just call it
|
||||
// `()` (the empty tuple).
|
||||
|
||||
let mt = ty::mt {ty: ty::mk_tup(self.tcx, ~[]),
|
||||
mutbl: m_imm};
|
||||
return self.cat_deref_common(node, base_cmt, deref_cnt, mt);
|
||||
let opaque_ty = ty::mk_tup(self.tcx, ~[]);
|
||||
return self.cat_deref_common(node, base_cmt, deref_cnt, opaque_ty);
|
||||
}
|
||||
|
||||
pub fn cat_deref<N:ast_node>(&self,
|
||||
@@ -662,25 +667,25 @@ pub fn cat_deref<N:ast_node>(&self,
|
||||
}
|
||||
};
|
||||
|
||||
return self.cat_deref_common(node, base_cmt, deref_cnt, mt);
|
||||
return self.cat_deref_common(node, base_cmt, deref_cnt, mt.ty);
|
||||
}
|
||||
|
||||
pub fn cat_deref_common<N:ast_node>(&self,
|
||||
node: N,
|
||||
base_cmt: cmt,
|
||||
deref_cnt: uint,
|
||||
mt: ty::mt)
|
||||
deref_ty: ty::t)
|
||||
-> cmt {
|
||||
match deref_kind(self.tcx, base_cmt.ty) {
|
||||
deref_ptr(ptr) => {
|
||||
// for unique ptrs, we inherit mutability from the
|
||||
// owning reference.
|
||||
let m = match ptr {
|
||||
uniq_ptr(*) => {
|
||||
self.inherited_mutability(base_cmt.mutbl, mt.mutbl)
|
||||
uniq_ptr => {
|
||||
base_cmt.mutbl.inherit()
|
||||
}
|
||||
gc_ptr(*) | region_ptr(_, _) | unsafe_ptr => {
|
||||
MutabilityCategory::from_mutbl(mt.mutbl)
|
||||
gc_ptr(m) | region_ptr(m, _) | unsafe_ptr(m) => {
|
||||
MutabilityCategory::from_mutbl(m)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -689,18 +694,18 @@ pub fn cat_deref_common<N:ast_node>(&self,
|
||||
span:node.span(),
|
||||
cat:cat_deref(base_cmt, deref_cnt, ptr),
|
||||
mutbl:m,
|
||||
ty:mt.ty
|
||||
ty:deref_ty
|
||||
}
|
||||
}
|
||||
|
||||
deref_interior(interior) => {
|
||||
let m = self.inherited_mutability(base_cmt.mutbl, mt.mutbl);
|
||||
let m = base_cmt.mutbl.inherit();
|
||||
@cmt_ {
|
||||
id:node.id(),
|
||||
span:node.span(),
|
||||
cat:cat_interior(base_cmt, interior),
|
||||
mutbl:m,
|
||||
ty:mt.ty
|
||||
ty:deref_ty
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -742,8 +747,8 @@ pub fn cat_index<N:ast_node>(&self,
|
||||
//! - `derefs`: the deref number to be used for
|
||||
//! the implicit index deref, if any (see above)
|
||||
|
||||
let mt = match ty::index(base_cmt.ty) {
|
||||
Some(mt) => mt,
|
||||
let element_ty = match ty::index(base_cmt.ty) {
|
||||
Some(ref mt) => mt.ty,
|
||||
None => {
|
||||
self.tcx.sess.span_bug(
|
||||
elt.span(),
|
||||
@@ -757,11 +762,11 @@ pub fn cat_index<N:ast_node>(&self,
|
||||
// for unique ptrs, we inherit mutability from the
|
||||
// owning reference.
|
||||
let m = match ptr {
|
||||
uniq_ptr(*) => {
|
||||
self.inherited_mutability(base_cmt.mutbl, mt.mutbl)
|
||||
uniq_ptr => {
|
||||
base_cmt.mutbl.inherit()
|
||||
}
|
||||
gc_ptr(_) | region_ptr(_, _) | unsafe_ptr => {
|
||||
MutabilityCategory::from_mutbl(mt.mutbl)
|
||||
gc_ptr(m) | region_ptr(m, _) | unsafe_ptr(m) => {
|
||||
MutabilityCategory::from_mutbl(m)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -771,16 +776,16 @@ pub fn cat_index<N:ast_node>(&self,
|
||||
span:elt.span(),
|
||||
cat:cat_deref(base_cmt, derefs, ptr),
|
||||
mutbl:m,
|
||||
ty:mt.ty
|
||||
ty:element_ty
|
||||
};
|
||||
|
||||
interior(elt, deref_cmt, base_cmt.ty, m, mt)
|
||||
interior(elt, deref_cmt, base_cmt.ty, m, element_ty)
|
||||
}
|
||||
|
||||
deref_interior(_) => {
|
||||
// fixed-length vectors have no deref
|
||||
let m = self.inherited_mutability(base_cmt.mutbl, mt.mutbl);
|
||||
interior(elt, base_cmt, base_cmt.ty, m, mt)
|
||||
let m = base_cmt.mutbl.inherit();
|
||||
interior(elt, base_cmt, base_cmt.ty, m, element_ty)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -788,14 +793,14 @@ fn interior<N: ast_node>(elt: N,
|
||||
of_cmt: cmt,
|
||||
vec_ty: ty::t,
|
||||
mutbl: MutabilityCategory,
|
||||
mt: ty::mt) -> cmt
|
||||
element_ty: ty::t) -> cmt
|
||||
{
|
||||
@cmt_ {
|
||||
id:elt.id(),
|
||||
span:elt.span(),
|
||||
cat:cat_interior(of_cmt, InteriorElement(element_kind(vec_ty))),
|
||||
mutbl:mutbl,
|
||||
ty:mt.ty
|
||||
ty:element_ty
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1130,7 +1135,7 @@ pub fn guarantor(@self) -> cmt {
|
||||
cat_stack_upvar(b) |
|
||||
cat_discr(b, _) |
|
||||
cat_interior(b, _) |
|
||||
cat_deref(b, _, uniq_ptr(*)) => {
|
||||
cat_deref(b, _, uniq_ptr) => {
|
||||
b.guarantor()
|
||||
}
|
||||
}
|
||||
@@ -1177,7 +1182,7 @@ pub fn freely_aliasable(&self) -> Option<AliasableReason> {
|
||||
|
||||
cat_downcast(b) |
|
||||
cat_stack_upvar(b) |
|
||||
cat_deref(b, _, uniq_ptr(*)) |
|
||||
cat_deref(b, _, uniq_ptr) |
|
||||
cat_interior(b, _) |
|
||||
cat_discr(b, _) => {
|
||||
b.freely_aliasable()
|
||||
@@ -1230,10 +1235,10 @@ fn repr(&self, tcx: ty::ctxt) -> ~str {
|
||||
|
||||
pub fn ptr_sigil(ptr: ptr_kind) -> ~str {
|
||||
match ptr {
|
||||
uniq_ptr(_) => ~"~",
|
||||
uniq_ptr => ~"~",
|
||||
gc_ptr(_) => ~"@",
|
||||
region_ptr(_, _) => ~"&",
|
||||
unsafe_ptr => ~"*"
|
||||
unsafe_ptr(_) => ~"*"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user