parent
996263a015
commit
2bc6547a5a
9 changed files with 96 additions and 23 deletions
|
@ -734,7 +734,8 @@ impl<'a> CheckLoanCtxt<'a> {
|
|||
mc::cat_static_item |
|
||||
mc::cat_copied_upvar(..) |
|
||||
mc::cat_deref(_, _, mc::UnsafePtr(..)) |
|
||||
mc::cat_deref(_, _, mc::BorrowedPtr(..)) => {
|
||||
mc::cat_deref(_, _, mc::BorrowedPtr(..)) |
|
||||
mc::cat_deref(_, _, mc::Implicit(..)) => {
|
||||
assert_eq!(cmt.mutbl, mc::McDeclared);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -131,6 +131,7 @@ fn check_and_get_illegal_move_origin(bccx: &BorrowckCtxt,
|
|||
cmt: &mc::cmt) -> Option<mc::cmt> {
|
||||
match cmt.cat {
|
||||
mc::cat_deref(_, _, mc::BorrowedPtr(..)) |
|
||||
mc::cat_deref(_, _, mc::Implicit(..)) |
|
||||
mc::cat_deref(_, _, mc::GcPtr) |
|
||||
mc::cat_deref(_, _, mc::UnsafePtr(..)) |
|
||||
mc::cat_upvar(..) | mc::cat_static_item |
|
||||
|
|
|
@ -72,6 +72,7 @@ impl<'a> GuaranteeLifetimeContext<'a> {
|
|||
mc::cat_arg(..) | // L-Local
|
||||
mc::cat_upvar(..) |
|
||||
mc::cat_deref(_, _, mc::BorrowedPtr(..)) | // L-Deref-Borrowed
|
||||
mc::cat_deref(_, _, mc::Implicit(..)) |
|
||||
mc::cat_deref(_, _, mc::UnsafePtr(..)) => {
|
||||
self.check_scope(self.scope(cmt))
|
||||
}
|
||||
|
@ -180,7 +181,8 @@ impl<'a> GuaranteeLifetimeContext<'a> {
|
|||
mc::cat_deref(_, _, mc::UnsafePtr(..)) => {
|
||||
ty::ReStatic
|
||||
}
|
||||
mc::cat_deref(_, _, mc::BorrowedPtr(_, r)) => {
|
||||
mc::cat_deref(_, _, mc::BorrowedPtr(_, r)) |
|
||||
mc::cat_deref(_, _, mc::Implicit(_, r)) => {
|
||||
r
|
||||
}
|
||||
mc::cat_downcast(ref cmt) |
|
||||
|
|
|
@ -113,6 +113,7 @@ fn group_errors_with_same_origin(errors: &Vec<MoveError>)
|
|||
fn report_cannot_move_out_of(bccx: &BorrowckCtxt, move_from: mc::cmt) {
|
||||
match move_from.cat {
|
||||
mc::cat_deref(_, _, mc::BorrowedPtr(..)) |
|
||||
mc::cat_deref(_, _, mc::Implicit(..)) |
|
||||
mc::cat_deref(_, _, mc::GcPtr) |
|
||||
mc::cat_deref(_, _, mc::UnsafePtr(..)) |
|
||||
mc::cat_upvar(..) | mc::cat_static_item |
|
||||
|
|
|
@ -122,7 +122,9 @@ impl<'a> RestrictionsContext<'a> {
|
|||
}
|
||||
|
||||
mc::cat_deref(cmt_base, _, mc::BorrowedPtr(ty::ImmBorrow, lt)) |
|
||||
mc::cat_deref(cmt_base, _, mc::BorrowedPtr(ty::UniqueImmBorrow, lt)) => {
|
||||
mc::cat_deref(cmt_base, _, mc::BorrowedPtr(ty::UniqueImmBorrow, lt)) |
|
||||
mc::cat_deref(cmt_base, _, mc::Implicit(ty::ImmBorrow, lt)) |
|
||||
mc::cat_deref(cmt_base, _, mc::Implicit(ty::UniqueImmBorrow, lt)) => {
|
||||
// R-Deref-Imm-Borrowed
|
||||
if !self.bccx.is_subregion_of(self.loan_region, lt) {
|
||||
self.bccx.report(
|
||||
|
@ -137,7 +139,8 @@ impl<'a> RestrictionsContext<'a> {
|
|||
Safe
|
||||
}
|
||||
|
||||
mc::cat_deref(cmt_base, _, pk @ mc::BorrowedPtr(ty::MutBorrow, lt)) => {
|
||||
mc::cat_deref(cmt_base, _, pk @ mc::BorrowedPtr(ty::MutBorrow, lt)) |
|
||||
mc::cat_deref(cmt_base, _, pk @ mc::Implicit(ty::MutBorrow, lt)) => {
|
||||
// R-Deref-Mut-Borrowed
|
||||
if !self.bccx.is_subregion_of(self.loan_region, lt) {
|
||||
self.bccx.report(
|
||||
|
|
|
@ -106,7 +106,8 @@ pub enum PointerKind {
|
|||
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
|
||||
|
@ -293,7 +294,7 @@ impl MutabilityCategory {
|
|||
OwnedPtr => {
|
||||
base_mutbl.inherit()
|
||||
}
|
||||
BorrowedPtr(borrow_kind, _) => {
|
||||
BorrowedPtr(borrow_kind, _) | Implicit(borrow_kind, _) => {
|
||||
MutabilityCategory::from_borrow_kind(borrow_kind)
|
||||
}
|
||||
GcPtr => {
|
||||
|
@ -422,7 +423,7 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
|
|||
-> 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);
|
||||
}
|
||||
|
@ -434,7 +435,7 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
|
|||
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, _) => {
|
||||
|
@ -443,9 +444,23 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
|
|||
}
|
||||
|
||||
ast::ExprIndex(ref base, _) => {
|
||||
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(_) => {
|
||||
let def = self.tcx().def_map.borrow().get_copy(&expr.id);
|
||||
|
@ -687,13 +702,14 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
|
|||
}
|
||||
|
||||
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,
|
||||
|
@ -717,7 +733,7 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
|
|||
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(),
|
||||
|
@ -731,10 +747,20 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
|
|||
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),
|
||||
|
@ -1073,7 +1099,7 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
|
|||
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -1129,6 +1155,9 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
|
|||
}
|
||||
_ => {
|
||||
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))
|
||||
}
|
||||
|
@ -1188,6 +1217,7 @@ impl cmt_ {
|
|||
cat_deref(_, _, UnsafePtr(..)) |
|
||||
cat_deref(_, _, GcPtr(..)) |
|
||||
cat_deref(_, _, BorrowedPtr(..)) |
|
||||
cat_deref(_, _, Implicit(..)) |
|
||||
cat_upvar(..) => {
|
||||
Rc::new((*self).clone())
|
||||
}
|
||||
|
@ -1212,7 +1242,9 @@ impl cmt_ {
|
|||
|
||||
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, _) |
|
||||
|
@ -1252,7 +1284,8 @@ impl cmt_ {
|
|||
Some(AliasableManaged)
|
||||
}
|
||||
|
||||
cat_deref(_, _, BorrowedPtr(ty::ImmBorrow, _)) => {
|
||||
cat_deref(_, _, BorrowedPtr(ty::ImmBorrow, _)) |
|
||||
cat_deref(_, _, Implicit(ty::ImmBorrow, _)) => {
|
||||
Some(AliasableBorrowed)
|
||||
}
|
||||
}
|
||||
|
@ -1300,9 +1333,12 @@ pub fn ptr_sigil(ptr: PointerKind) -> &'static str {
|
|||
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(_) => "*"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1219,7 +1219,8 @@ fn link_region(rcx: &Rcx,
|
|||
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
|
||||
|
@ -1340,7 +1341,8 @@ fn adjust_upvar_borrow_kind_for_mut(rcx: &Rcx,
|
|||
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
|
||||
|
@ -1394,7 +1396,8 @@ fn adjust_upvar_borrow_kind_for_unique(rcx: &Rcx, cmt: mc::cmt) {
|
|||
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
|
||||
|
|
26
src/test/compile-fail/borrowck-overloaded-index-2.rs
Normal file
26
src/test/compile-fail/borrowck-overloaded-index-2.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
struct MyVec<T> {
|
||||
data: Vec<T>,
|
||||
}
|
||||
|
||||
impl<T> Index<uint, T> for MyVec<T> {
|
||||
fn index<'a>(&'a self, &i: &uint) -> &'a T {
|
||||
self.data.get(i)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let v = MyVec { data: vec!(box 1i, box 2, box 3) };
|
||||
let good = &v[0]; // Shouldn't fail here
|
||||
let bad = v[0];
|
||||
//~^ ERROR cannot move out of dereference (dereference is implicit, due to indexing)
|
||||
}
|
|
@ -58,7 +58,7 @@ fn main() {
|
|||
x: 1,
|
||||
};
|
||||
s[2] = 20;
|
||||
//~^ ERROR cannot assign to immutable indexed content
|
||||
//~^ ERROR cannot assign to immutable dereference (dereference is implicit, due to indexing)
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue