OwnedPtr,
GcPtr,
BorrowedPtr(ty::BorrowKind, ty::Region),
- UnsafePtr(ast::Mutability),
+ Implicit(ty::BorrowKind, ty::Region), // Implicit deref of a borrowed ptr.
+ UnsafePtr(ast::Mutability)
}
// We use the term "interior" to mean "something reachable from the
OwnedPtr => {
base_mutbl.inherit()
}
- BorrowedPtr(borrow_kind, _) => {
+ BorrowedPtr(borrow_kind, _) | Implicit(borrow_kind, _) => {
MutabilityCategory::from_borrow_kind(borrow_kind)
}
GcPtr => {
-> McResult<cmt> {
let mut cmt = if_ok!(self.cat_expr_unadjusted(expr));
for deref in range(1u, autoderefs + 1) {
- cmt = self.cat_deref(expr, cmt, deref);
+ cmt = self.cat_deref(expr, cmt, deref, false);
}
return Ok(cmt);
}
match expr.node {
ast::ExprUnary(ast::UnDeref, ref e_base) => {
let base_cmt = if_ok!(self.cat_expr(&**e_base));
- Ok(self.cat_deref(expr, base_cmt, 0))
+ Ok(self.cat_deref(expr, base_cmt, 0, false))
}
ast::ExprField(ref base, f_name, _) => {
}
ast::ExprIndex(ref base, _) => {
- let base_cmt = if_ok!(self.cat_expr(&**base));
- Ok(self.cat_index(expr, base_cmt, 0))
+ let method_call = typeck::MethodCall::expr(expr.id());
+ match self.typer.node_method_ty(method_call) {
+ Some(method_ty) => {
+ // If this is an index implemented by a method call, then it will
+ // include an implicit deref of the result.
+ let ret_ty = ty::ty_fn_ret(method_ty);
+ Ok(self.cat_deref(expr,
+ self.cat_rvalue_node(expr.id(),
+ expr.span(),
+ ret_ty), 1, true))
+ }
+ None => {
+ let base_cmt = if_ok!(self.cat_expr(&**base));
+ Ok(self.cat_index(expr, base_cmt, 0))
+ }
+ }
}
ast::ExprPath(_) => {
}
pub fn cat_deref_obj<N:ast_node>(&self, node: &N, base_cmt: cmt) -> cmt {
- self.cat_deref_common(node, base_cmt, 0, ty::mk_nil())
+ self.cat_deref_common(node, base_cmt, 0, ty::mk_nil(), false)
}
fn cat_deref<N:ast_node>(&self,
node: &N,
base_cmt: cmt,
- deref_cnt: uint)
+ deref_cnt: uint,
+ implicit: bool)
-> cmt {
let adjustment = match self.typer.adjustments().borrow().find(&node.id()) {
Some(&ty::AutoObject(..)) => typeck::AutoObject,
None => base_cmt
};
match ty::deref(base_cmt.ty, true) {
- Some(mt) => self.cat_deref_common(node, base_cmt, deref_cnt, mt.ty),
+ Some(mt) => self.cat_deref_common(node, base_cmt, deref_cnt, mt.ty, implicit),
None => {
self.tcx().sess.span_bug(
node.span(),
node: &N,
base_cmt: cmt,
deref_cnt: uint,
- deref_ty: ty::t)
+ deref_ty: ty::t,
+ implicit: bool)
-> cmt {
let (m, cat) = match deref_kind(self.tcx(), base_cmt.ty) {
deref_ptr(ptr) => {
+ let ptr = if implicit {
+ match ptr {
+ BorrowedPtr(bk, r) => Implicit(bk, r),
+ _ => self.tcx().sess.span_bug(node.span(),
+ "Implicit deref of non-borrowed pointer")
+ }
+ } else {
+ ptr
+ };
// for unique ptrs, we inherit mutability from the
// owning reference.
(MutabilityCategory::from_pointer_kind(base_cmt.mutbl, ptr),
ast::PatBox(ref subpat) | ast::PatRegion(ref subpat) => {
// @p1, ~p1
- let subcmt = self.cat_deref(pat, cmt, 0);
+ let subcmt = self.cat_deref(pat, cmt, 0, false);
if_ok!(self.cat_pattern(subcmt, &**subpat, op));
}
}
_ => {
match pk {
+ Implicit(..) => {
+ "dereference (dereference is implicit, due to indexing)".to_string()
+ }
OwnedPtr | GcPtr => format!("dereference of `{}`", ptr_sigil(pk)),
_ => format!("dereference of `{}`-pointer", ptr_sigil(pk))
}
cat_deref(_, _, UnsafePtr(..)) |
cat_deref(_, _, GcPtr(..)) |
cat_deref(_, _, BorrowedPtr(..)) |
+ cat_deref(_, _, Implicit(..)) |
cat_upvar(..) => {
Rc::new((*self).clone())
}
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_deref(ref b, _, OwnedPtr) |
cat_interior(ref b, _) |
Some(AliasableManaged)
}
- cat_deref(_, _, BorrowedPtr(ty::ImmBorrow, _)) => {
+ cat_deref(_, _, BorrowedPtr(ty::ImmBorrow, _)) |
+ cat_deref(_, _, Implicit(ty::ImmBorrow, _)) => {
Some(AliasableBorrowed)
}
}
match ptr {
OwnedPtr => "Box",
GcPtr => "Gc",
- BorrowedPtr(ty::ImmBorrow, _) => "&",
- BorrowedPtr(ty::MutBorrow, _) => "&mut",
- BorrowedPtr(ty::UniqueImmBorrow, _) => "&unique",
+ BorrowedPtr(ty::ImmBorrow, _) |
+ Implicit(ty::ImmBorrow, _) => "&",
+ BorrowedPtr(ty::MutBorrow, _) |
+ Implicit(ty::MutBorrow, _) => "&mut",
+ BorrowedPtr(ty::UniqueImmBorrow, _) |
+ Implicit(ty::UniqueImmBorrow, _) => "&unique",
UnsafePtr(_) => "*"
}
}
kind.repr(rcx.tcx()),
cmt_borrowed.repr(rcx.tcx()));
match cmt_borrowed.cat.clone() {
- mc::cat_deref(base, _, mc::BorrowedPtr(_, r_borrowed)) => {
+ mc::cat_deref(base, _, mc::BorrowedPtr(_, r_borrowed)) |
+ mc::cat_deref(base, _, mc::Implicit(_, r_borrowed)) => {
// References to an upvar `x` are translated to
// `*x`, since that is what happens in the
// underlying machine. We detect such references
continue;
}
- mc::cat_deref(base, _, mc::BorrowedPtr(..)) => {
+ mc::cat_deref(base, _, mc::BorrowedPtr(..)) |
+ mc::cat_deref(base, _, mc::Implicit(..)) => {
match base.cat {
mc::cat_upvar(ref upvar_id, _) => {
// if this is an implicit deref of an
continue;
}
- mc::cat_deref(base, _, mc::BorrowedPtr(..)) => {
+ mc::cat_deref(base, _, mc::BorrowedPtr(..)) |
+ mc::cat_deref(base, _, mc::Implicit(..)) => {
match base.cat {
mc::cat_upvar(ref upvar_id, _) => {
// if this is an implicit deref of an