auto merge of #11485 : eddyb/rust/sweep-old-rust, r=nikomatsakis

This commit is contained in:
bors 2014-01-14 12:32:11 -08:00
commit 9075025c7b
39 changed files with 191 additions and 262 deletions

View File

@ -782,7 +782,7 @@ fn get_explicit_self(item: ebml::Doc) -> ast::ExplicitSelf_ {
match explicit_self_kind as char {
's' => ast::SelfStatic,
'v' => ast::SelfValue(get_mutability(string[1])),
'@' => ast::SelfBox(get_mutability(string[1])),
'@' => ast::SelfBox,
'~' => ast::SelfUniq(get_mutability(string[1])),
// FIXME(#4846) expl. region
'&' => ast::SelfRegion(None, get_mutability(string[1])),

View File

@ -687,9 +687,8 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::Explic
ebml_w.writer.write(&[ '&' as u8 ]);
encode_mutability(ebml_w, m);
}
SelfBox(m) => {
SelfBox => {
ebml_w.writer.write(&[ '@' as u8 ]);
encode_mutability(ebml_w, m);
}
SelfUniq(m) => {
ebml_w.writer.write(&[ '~' as u8 ]);

View File

@ -343,7 +343,7 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
return ty::mk_self(st.tcx, did);
}
'@' => return ty::mk_box(st.tcx, parse_ty(st, |x,y| conv(x,y))),
'~' => return ty::mk_uniq(st.tcx, parse_mt(st, |x,y| conv(x,y))),
'~' => return ty::mk_uniq(st.tcx, parse_ty(st, |x,y| conv(x,y))),
'*' => return ty::mk_ptr(st.tcx, parse_mt(st, |x,y| conv(x,y))),
'&' => {
let r = parse_region(st, |x,y| conv(x,y));

View File

@ -292,7 +292,7 @@ fn enc_sty(w: &mut MemWriter, cx: @ctxt, st: &ty::sty) {
mywrite!(w, "]");
}
ty::ty_box(typ) => { mywrite!(w, "@"); enc_ty(w, cx, typ); }
ty::ty_uniq(mt) => { mywrite!(w, "~"); enc_mt(w, cx, mt); }
ty::ty_uniq(typ) => { mywrite!(w, "~"); enc_ty(w, cx, typ); }
ty::ty_ptr(mt) => { mywrite!(w, "*"); enc_mt(w, cx, mt); }
ty::ty_rptr(r, mt) => {
mywrite!(w, "&");

View File

@ -248,7 +248,7 @@ data as mutable).
2. `LIFETIME(LV, LT, MQ)`: The lifetime of the borrow does not exceed
the lifetime of the value being borrowed. This pass is also
responsible for inserting root annotations to keep managed values
alive and for dynamically freezing `@mut` boxes.
alive.
3. `RESTRICTIONS(LV, LT, ACTIONS) = RS`: This pass checks and computes the
restrictions to maintain memory safety. These are the restrictions
@ -308,22 +308,17 @@ be borrowed if MQ is immutable or const:
### Checking mutability of mutable pointer types
`&mut T` and `@mut T` can be frozen, so it is acceptable to borrow
them as either imm or mut:
`&mut T` can be frozen, so it is acceptable to borrow it as either imm or mut:
MUTABILITY(*LV, MQ) // M-Deref-Borrowed-Mut
TYPE(LV) = &mut Ty
MUTABILITY(*LV, MQ) // M-Deref-Managed-Mut
TYPE(LV) = @mut Ty
## Checking lifetime
These rules aim to ensure that no data is borrowed for a scope that
exceeds its lifetime. In addition, these rules manage the rooting and
dynamic freezing of `@` and `@mut` values. These two computations wind
up being intimately related. Formally, we define a predicate
`LIFETIME(LV, LT, MQ)`, which states that "the lvalue `LV` can be
These rules aim to ensure that no data is borrowed for a scope that exceeds
its lifetime. In addition, these rules manage the rooting of `@` values.
These two computations wind up being intimately related. Formally, we define
a predicate `LIFETIME(LV, LT, MQ)`, which states that "the lvalue `LV` can be
safely borrowed for the lifetime `LT` with mutability `MQ`". The Rust
code corresponding to this predicate is the module
`middle::borrowck::gather_loans::lifetime`.
@ -352,7 +347,7 @@ The scope of a managed referent is also the scope of the pointer. This
is a conservative approximation, since there may be other aliases fo
that same managed box that would cause it to live longer:
SCOPE(*LV) = SCOPE(LV) if LV has type @T or @mut T
SCOPE(*LV) = SCOPE(LV) if LV has type @T
The scope of a borrowed referent is the scope associated with the
pointer. This is a conservative approximation, since the data that
@ -441,29 +436,6 @@ makes a note in a side-table that the box `LV` must be rooted into the
stack when `*LV` is evaluated, and that this root can be released when
the scope `LT` exits.
### Checking lifetime for derefs of managed, mutable pointers
Loans of the contents of mutable managed pointers are simpler in some
ways that loans of immutable managed pointers, because we can never
rely on the user to root them (since the contents are, after all,
mutable). This means that the burden always falls to the compiler, so
there is only one rule:
LIFETIME(*LV, LT, MQ) // L-Deref-Managed-Mut-Compiler-Root
TYPE(LV) = @mut Ty
LT <= innermost enclosing loop/func
ROOT LV at *LV for LT
LOCK LV at *LV as MQ for LT
Note that there is an additional clause this time `LOCK LV at *LV as
MQ for LT`. This clause states that in addition to rooting `LV`, the
compiler should also "lock" the box dynamically, meaning that we
register that the box has been borrowed as mutable or immutable,
depending on `MQ`. This lock will fail if the box has already been
borrowed and either the old loan or the new loan is a mutable loan
(multiple immutable loans are okay). The lock is released as we exit
the scope `LT`.
## Computing the restrictions
The final rules govern the computation of *restrictions*, meaning that
@ -835,15 +807,6 @@ prohibited from both freezes and claims. This would avoid the need to
prevent `const` borrows of the base pointer when the referent is
borrowed.
### Restrictions for loans of mutable managed referents
With `@mut` referents, we don't make any static guarantees. But as a
convenience, we still register a restriction against `*LV`, because
that way if we *can* find a simple static error, we will:
RESTRICTIONS(*LV, LT, ACTIONS) = [*LV, ACTIONS] // R-Deref-Managed-Borrowed
TYPE(LV) = @mut Ty
# Moves and initialization
The borrow checker is also in charge of ensuring that:

View File

@ -137,7 +137,7 @@ impl<'a> GuaranteeLifetimeContext<'a> {
//
// As a second example, consider *this* scenario:
//
// let x = @mut @Some(3);
// let x = @@Some(3);
// match x { @@Some(y) {...} @@None {...} }
//
// Here again, `x` need only be rooted in the `some` arm.
@ -156,7 +156,7 @@ impl<'a> GuaranteeLifetimeContext<'a> {
// with a second basic block. However, the naive approach
// also yielded suboptimal results for patterns like:
//
// let x = @mut @...;
// let x = @@...;
// match x { @@some_variant(y) | @@some_other_variant(y) =>
//
// The reason is that we would root the value once for

View File

@ -409,7 +409,7 @@ fn visit_fn(v: &mut LivenessVisitor,
match *fk {
visit::FkMethod(_, _, method) => {
match method.explicit_self.node {
SelfValue(_) | SelfRegion(..) | SelfBox(_) | SelfUniq(_) => {
SelfValue(_) | SelfRegion(..) | SelfBox | SelfUniq(_) => {
fn_maps.add_variable(Arg(method.self_id,
special_idents::self_));
}

View File

@ -357,20 +357,18 @@ pub fn malloc_raw_dyn<'a>(
rslt(r.bcx, PointerCast(r.bcx, r.val, llty_value.ptr_to()))
} else {
// we treat ~fn, @fn and @[] as @ here, which isn't ideal
let (mk_fn, langcall) = match heap {
let langcall = match heap {
heap_managed | heap_managed_unique => {
(ty::mk_imm_box,
require_alloc_fn(bcx, t, MallocFnLangItem))
require_alloc_fn(bcx, t, MallocFnLangItem)
}
heap_exchange_closure => {
(ty::mk_imm_box,
require_alloc_fn(bcx, t, ClosureExchangeMallocFnLangItem))
require_alloc_fn(bcx, t, ClosureExchangeMallocFnLangItem)
}
_ => fail!("heap_exchange already handled")
};
// Grab the TypeRef type of box_ptr_ty.
let box_ptr_ty = mk_fn(bcx.tcx(), t);
let box_ptr_ty = ty::mk_box(bcx.tcx(), t);
let llty = type_of(ccx, box_ptr_ty);
// Get the tydesc for the body:

View File

@ -131,11 +131,6 @@ impl EnvValue {
}
}
pub fn mk_tuplified_uniq_cbox_ty(tcx: ty::ctxt, cdata_ty: ty::t) -> ty::t {
let cbox_ty = tuplify_box_ty(tcx, cdata_ty);
return ty::mk_imm_uniq(tcx, cbox_ty);
}
// Given a closure ty, emits a corresponding tuple ty
pub fn mk_closure_tys(tcx: ty::ctxt,
bound_values: &[EnvValue])

View File

@ -569,7 +569,7 @@ impl Datum {
let (content_ty, header) = match ty::get(self.ty).sty {
ty::ty_box(typ) => (typ, true),
ty::ty_uniq(mt) => (mt.ty, false),
ty::ty_uniq(typ) => (typ, false),
ty::ty_vec(_, ty::vstore_uniq) | ty::ty_str(ty::vstore_uniq) => {
let unit_ty = ty::sequence_element_type(bcx.tcx(), self.ty);
let unboxed_vec_ty = ty::mk_mut_unboxed_vec(bcx.tcx(), unit_ty);

View File

@ -2164,12 +2164,15 @@ fn type_metadata(cx: &CrateContext,
}
}
},
ty::ty_uniq(ref mt) if ty::type_contents(cx.tcx, mt.ty).owns_managed() => {
create_pointer_to_box_metadata(cx, t, mt.ty)
},
ty::ty_uniq(ref mt) |
ty::ty_ptr(ref mt) |
ty::ty_rptr(_, ref mt) => {
ty::ty_uniq(typ) => {
if ty::type_contents(cx.tcx, typ).owns_managed() {
create_pointer_to_box_metadata(cx, t, typ)
} else {
let pointee = type_metadata(cx, typ, usage_site_span);
pointer_type_metadata(cx, t, pointee)
}
}
ty::ty_ptr(ref mt) | ty::ty_rptr(_, ref mt) => {
let pointee = type_metadata(cx, mt.ty, usage_site_span);
pointer_type_metadata(cx, t, pointee)
},
@ -2193,7 +2196,7 @@ fn type_metadata(cx: &CrateContext,
let mut created_types = debug_context(cx).created_types.borrow_mut();
created_types.get().insert(cache_id, type_metadata);
return type_metadata;
type_metadata
}
#[deriving(Eq)]

View File

@ -108,22 +108,26 @@ fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t {
}
if field == abi::tydesc_field_take_glue && ty::type_is_boxed(t) {
return ty::mk_imm_box(tcx, ty::mk_nil());
return ty::mk_box(tcx, ty::mk_nil());
}
if field == abi::tydesc_field_drop_glue {
match ty::get(t).sty {
ty::ty_box(typ)
if !ty::type_needs_drop(tcx, typ) =>
return ty::mk_imm_box(tcx, ty::mk_nil()),
return ty::mk_box(tcx, ty::mk_nil()),
ty::ty_vec(mt, ty::vstore_box)
if !ty::type_needs_drop(tcx, mt.ty) =>
return ty::mk_imm_box(tcx, ty::mk_nil()),
return ty::mk_box(tcx, ty::mk_nil()),
ty::ty_uniq(mt) | ty::ty_vec(mt, ty::vstore_uniq)
ty::ty_uniq(typ)
if !ty::type_needs_drop(tcx, typ) =>
return ty::mk_uniq(tcx, ty::mk_nil()),
ty::ty_vec(mt, ty::vstore_uniq)
if !ty::type_needs_drop(tcx, mt.ty) =>
return ty::mk_imm_uniq(tcx, ty::mk_nil()),
return ty::mk_uniq(tcx, ty::mk_nil()),
_ => {}
}

View File

@ -176,6 +176,7 @@ impl<'a> Reflector<'a> {
self.visit("vec", values)
}
// Should rename to str_*/vec_*.
ty::ty_str(vst) => {
let (name, extra) = self.vstore_name_and_extra(t, vst);
self.visit(~"estr_" + name, extra)
@ -189,6 +190,7 @@ impl<'a> Reflector<'a> {
self.visit(~"evec_" + name, extra)
}
}
// Should remove mt from box and uniq.
ty::ty_box(typ) => {
let extra = self.c_mt(&ty::mt {
ty: typ,
@ -196,8 +198,11 @@ impl<'a> Reflector<'a> {
});
self.visit("box", extra)
}
ty::ty_uniq(ref mt) => {
let extra = self.c_mt(mt);
ty::ty_uniq(typ) => {
let extra = self.c_mt(&ty::mt {
ty: typ,
mutbl: ast::MutImmutable,
});
if ty::type_contents(bcx.tcx(), t).owns_managed() {
self.visit("uniq_managed", extra)
} else {

View File

@ -39,14 +39,14 @@ pub fn expand_boxed_vec_ty(tcx: ty::ctxt, t: ty::t) -> ty::t {
let unit_ty = ty::sequence_element_type(tcx, t);
let unboxed_vec_ty = ty::mk_mut_unboxed_vec(tcx, unit_ty);
match ty::get(t).sty {
ty::ty_str(ty::vstore_uniq) | ty::ty_vec(_, ty::vstore_uniq) => {
ty::mk_imm_uniq(tcx, unboxed_vec_ty)
}
ty::ty_str(ty::vstore_box) | ty::ty_vec(_, ty::vstore_box) => {
ty::mk_imm_box(tcx, unboxed_vec_ty)
}
_ => tcx.sess.bug("non boxed-vec type \
in tvec::expand_boxed_vec_ty")
ty::ty_str(ty::vstore_uniq) | ty::ty_vec(_, ty::vstore_uniq) => {
ty::mk_uniq(tcx, unboxed_vec_ty)
}
ty::ty_str(ty::vstore_box) | ty::ty_vec(_, ty::vstore_box) => {
ty::mk_box(tcx, unboxed_vec_ty)
}
_ => tcx.sess.bug("non boxed-vec type \
in tvec::expand_boxed_vec_ty")
}
}

View File

@ -244,9 +244,9 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
let ty = type_of(cx, typ);
Type::smart_ptr(cx, &ty).ptr_to()
}
ty::ty_uniq(ref mt) => {
let ty = type_of(cx, mt.ty);
if ty::type_contents(cx.tcx, mt.ty).owns_managed() {
ty::ty_uniq(typ) => {
let ty = type_of(cx, typ);
if ty::type_contents(cx.tcx, typ).owns_managed() {
Type::unique(cx, &ty).ptr_to()
} else {
ty.ptr_to()

View File

@ -8,8 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Logic relating to rooting and write guards for managed values
//! (`@` and `@mut`). This code is primarily for use by datum;
//! Logic relating to rooting and write guards for managed values.
//! This code is primarily for use by datum;
//! it exists in its own module both to keep datum.rs bite-sized
//! and for each in debugging (e.g., so you can use
//! `RUST_LOG=rustc::middle::trans::write_guard`).

View File

@ -629,7 +629,7 @@ pub enum sty {
ty_str(vstore),
ty_enum(DefId, substs),
ty_box(t),
ty_uniq(mt),
ty_uniq(t),
ty_vec(mt, vstore),
ty_ptr(mt),
ty_rptr(Region, mt),
@ -1091,8 +1091,10 @@ pub fn mk_t(cx: ctxt, st: sty) -> t {
_ => {}
}
}
&ty_box(ref tt) => flags |= get(*tt).flags,
&ty_uniq(ref m) | &ty_vec(ref m, _) | &ty_ptr(ref m) |
&ty_box(tt) | &ty_uniq(tt) => {
flags |= get(tt).flags
}
&ty_vec(ref m, _) | &ty_ptr(ref m) |
&ty_unboxed_vec(ref m) => {
flags |= get(m.ty).flags;
}
@ -1234,15 +1236,7 @@ pub fn mk_enum(cx: ctxt, did: ast::DefId, substs: substs) -> t {
pub fn mk_box(cx: ctxt, ty: t) -> t { mk_t(cx, ty_box(ty)) }
pub fn mk_imm_box(cx: ctxt, ty: t) -> t {
mk_box(cx, ty)
}
pub fn mk_uniq(cx: ctxt, tm: mt) -> t { mk_t(cx, ty_uniq(tm)) }
pub fn mk_imm_uniq(cx: ctxt, ty: t) -> t {
mk_uniq(cx, mt {ty: ty, mutbl: ast::MutImmutable})
}
pub fn mk_uniq(cx: ctxt, ty: t) -> t { mk_t(cx, ty_uniq(ty)) }
pub fn mk_ptr(cx: ctxt, tm: mt) -> t { mk_t(cx, ty_ptr(tm)) }
@ -1355,9 +1349,9 @@ pub fn maybe_walk_ty(ty: t, f: |t| -> bool) {
ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) |
ty_str(_) | ty_type | ty_self(_) |
ty_opaque_closure_ptr(_) | ty_infer(_) | ty_param(_) | ty_err => {}
ty_box(ref ty) => maybe_walk_ty(*ty, f),
ty_box(ty) | ty_uniq(ty) => maybe_walk_ty(ty, f),
ty_vec(ref tm, _) | ty_unboxed_vec(ref tm) | ty_ptr(ref tm) |
ty_rptr(_, ref tm) | ty_uniq(ref tm) => {
ty_rptr(_, ref tm) => {
maybe_walk_ty(tm.ty, f);
}
ty_enum(_, ref substs) | ty_struct(_, ref substs) |
@ -2026,6 +2020,10 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
tc_ty(cx, typ, cache).managed_pointer()
}
ty_uniq(typ) => {
tc_ty(cx, typ, cache).owned_pointer()
}
ty_trait(_, _, store, mutbl, bounds) => {
object_contents(cx, store, mutbl, bounds)
}
@ -2039,10 +2037,6 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
borrowed_contents(r, mt.mutbl))
}
ty_uniq(mt) => {
tc_mt(cx, mt, cache).owned_pointer()
}
ty_vec(mt, vstore_uniq) => {
tc_mt(cx, mt, cache).owned_pointer()
}
@ -2318,10 +2312,9 @@ pub fn is_instantiable(cx: ctxt, r_ty: t) -> bool {
ty_unboxed_vec(_) => {
false
}
ty_box(typ) => {
ty_box(typ) | ty_uniq(typ) => {
type_requires(cx, seen, r_ty, typ)
}
ty_uniq(ref mt) |
ty_rptr(_, ref mt) => {
type_requires(cx, seen, r_ty, mt.ty)
}
@ -2596,22 +2589,22 @@ pub fn deref(t: t, explicit: bool) -> Option<mt> {
pub fn deref_sty(sty: &sty, explicit: bool) -> Option<mt> {
match *sty {
ty_box(typ) => {
Some(mt {
ty: typ,
mutbl: ast::MutImmutable,
})
}
ty_box(typ) | ty_uniq(typ) => {
Some(mt {
ty: typ,
mutbl: ast::MutImmutable,
})
}
ty_rptr(_, mt) | ty_uniq(mt) => {
Some(mt)
}
ty_rptr(_, mt) => {
Some(mt)
}
ty_ptr(mt) if explicit => {
Some(mt)
}
ty_ptr(mt) if explicit => {
Some(mt)
}
_ => None
_ => None
}
}
@ -4861,9 +4854,8 @@ pub fn hash_crate_independent(tcx: ctxt, t: t, local_hash: @str) -> u64 {
ty_box(_) => {
hash.input([9]);
}
ty_uniq(m) => {
ty_uniq(_) => {
hash.input([10]);
mt(&mut hash, m);
}
ty_vec(m, v) => {
hash.input([11]);

View File

@ -143,8 +143,8 @@ pub fn super_fold_sty<T:TypeFolder>(this: &mut T,
ty::ty_box(typ) => {
ty::ty_box(this.fold_ty(typ))
}
ty::ty_uniq(ref tm) => {
ty::ty_uniq(this.fold_mt(tm))
ty::ty_uniq(typ) => {
ty::ty_uniq(this.fold_ty(typ))
}
ty::ty_ptr(ref tm) => {
ty::ty_ptr(this.fold_mt(tm))

View File

@ -410,7 +410,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
ast::TyUniq(ty) => {
let mt = ast::MutTy { ty: ty, mutbl: ast::MutImmutable };
mk_pointer(this, rscope, &mt, ty::vstore_uniq,
|tmt| ty::mk_uniq(tcx, tmt))
|tmt| ty::mk_uniq(tcx, tmt.ty))
}
ast::TyVec(ty) => {
tcx.sess.span_err(ast_ty.span, "bare `[]` is not a type");
@ -691,13 +691,11 @@ fn ty_of_method_or_bare_fn<AC:AstConv>(
ty::mt {ty: self_info.untransformed_self_ty,
mutbl: mutability}))
}
ast::SelfBox(_) => {
ast::SelfBox => {
Some(ty::mk_box(this.tcx(), self_info.untransformed_self_ty))
}
ast::SelfUniq(_) => {
Some(ty::mk_uniq(this.tcx(),
ty::mt {ty: self_info.untransformed_self_ty,
mutbl: ast::MutImmutable}))
Some(ty::mk_uniq(this.tcx(), self_info.untransformed_self_ty))
}
}
}

View File

@ -670,7 +670,7 @@ pub fn check_pointer_pat(pcx: &pat_ctxt,
};
match *structure_of(fcx, span, expected) {
ty::ty_uniq(e_inner) if pointer_kind == Send => {
check_inner(e_inner.ty);
check_inner(e_inner);
}
ty::ty_rptr(_, e_inner) if pointer_kind == Borrowed => {
check_inner(e_inner.ty);

View File

@ -623,9 +623,9 @@ impl<'a> LookupContext<'a> {
* consuming the original pointer.
*
* You might think that this would be a natural byproduct of
* the auto-deref/auto-ref process. This is true for `@mut T`
* but not for an `&mut T` receiver. With `@mut T`, we would
* begin by testing for methods with a self type `@mut T`,
* the auto-deref/auto-ref process. This is true for `~T`
* but not for an `&mut T` receiver. With `~T`, we would
* begin by testing for methods with a self type `~T`,
* then autoderef to `T`, then autoref to `&mut T`. But with
* an `&mut T` receiver the process begins with `&mut T`, only
* without any autoadjustments.
@ -1057,15 +1057,15 @@ impl<'a> LookupContext<'a> {
*
* trait Foo {
* fn r_method<'a>(&'a self);
* fn m_method(@mut self);
* fn u_method(~self);
* }
*
* Now, assuming that `r_method` is being called, we want the
* result to be `&'a Foo`. Assuming that `m_method` is being
* called, we want the result to be `@mut Foo`. Of course,
* result to be `&'a Foo`. Assuming that `u_method` is being
* called, we want the result to be `~Foo`. Of course,
* this transformation has already been done as part of
* `method_ty.transformed_self_ty`, but there the
* type is expressed in terms of `Self` (i.e., `&'a Self`, `@mut Self`).
* `method_ty.transformed_self_ty`, but there the type
* is expressed in terms of `Self` (i.e., `&'a Self`, `~Self`).
* Because objects are not standalone types, we can't just substitute
* `s/Self/Foo/`, so we must instead perform this kind of hokey
* match below.
@ -1081,7 +1081,7 @@ impl<'a> LookupContext<'a> {
ast::SelfValue(_) => {
ty::mk_err() // error reported in `enforce_object_limitations()`
}
ast::SelfRegion(..) | ast::SelfBox(..) | ast::SelfUniq(..) => {
ast::SelfRegion(..) | ast::SelfBox | ast::SelfUniq(..) => {
let transformed_self_ty =
method_ty.transformed_self_ty.clone().unwrap();
match ty::get(transformed_self_ty).sty {
@ -1095,9 +1095,9 @@ impl<'a> LookupContext<'a> {
substs, BoxTraitStore, ast::MutImmutable,
ty::EmptyBuiltinBounds())
}
ty::ty_uniq(mt) => { // must be SelfUniq
ty::ty_uniq(_) => { // must be SelfUniq
ty::mk_trait(self.tcx(), trait_def_id,
substs, UniqTraitStore, mt.mutbl,
substs, UniqTraitStore, ast::MutImmutable,
ty::EmptyBuiltinBounds())
}
_ => {
@ -1144,7 +1144,7 @@ impl<'a> LookupContext<'a> {
through an object");
}
ast::SelfRegion(..) | ast::SelfBox(..) | ast::SelfUniq(..) => {}
ast::SelfRegion(..) | ast::SelfBox | ast::SelfUniq(..) => {}
}
if ty::type_has_self(method_fty) { // reason (a) above
@ -1219,15 +1219,14 @@ impl<'a> LookupContext<'a> {
}
}
SelfBox(m) => {
SelfBox => {
debug!("(is relevant?) explicit self is a box");
match ty::get(rcvr_ty).sty {
ty::ty_box(typ) => {
rcvr_matches_ty(self.fcx, typ, candidate)
}
ty::ty_trait(self_did, _, BoxTraitStore, self_m, _) => {
mutability_matches(self_m, m) &&
ty::ty_trait(self_did, _, BoxTraitStore, ast::MutImmutable, _) => {
rcvr_matches_object(self_did, candidate)
}
@ -1238,8 +1237,8 @@ impl<'a> LookupContext<'a> {
SelfUniq(_) => {
debug!("(is relevant?) explicit self is a unique pointer");
match ty::get(rcvr_ty).sty {
ty::ty_uniq(mt) => {
rcvr_matches_ty(self.fcx, mt.ty, candidate)
ty::ty_uniq(typ) => {
rcvr_matches_ty(self.fcx, typ, candidate)
}
ty::ty_trait(self_did, _, UniqTraitStore, _, _) => {

View File

@ -1334,7 +1334,7 @@ pub fn do_autoderef(fcx: @FnCtxt, sp: Span, t: ty::t) -> (ty::t, uint) {
// Some extra checks to detect weird cycles and so forth:
match *sty {
ty::ty_box(inner) => {
ty::ty_box(inner) | ty::ty_uniq(inner) => {
match ty::get(t1).sty {
ty::ty_infer(ty::TyVar(v1)) => {
ty::occurs_check(fcx.ccx.tcx, sp, v1,
@ -1343,7 +1343,7 @@ pub fn do_autoderef(fcx: @FnCtxt, sp: Span, t: ty::t) -> (ty::t, uint) {
_ => ()
}
}
ty::ty_uniq(inner) | ty::ty_rptr(_, inner) => {
ty::ty_rptr(_, inner) => {
match ty::get(t1).sty {
ty::ty_infer(ty::TyVar(v1)) => {
ty::occurs_check(fcx.ccx.tcx, sp, v1,
@ -2697,10 +2697,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
let def_id = ast_util::def_id_of_def(definition);
match tcx.lang_items.items[ExchangeHeapLangItem as uint] {
Some(item_def_id) if def_id == item_def_id => {
fcx.write_ty(id, ty::mk_uniq(tcx, ty::mt {
ty: fcx.expr_ty(subexpr),
mutbl: ast::MutImmutable,
}));
fcx.write_ty(id, ty::mk_uniq(tcx,
fcx.expr_ty(subexpr)));
checked = true
}
Some(_) | None => {}
@ -2806,13 +2804,12 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
ast::ExprUnary(callee_id, unop, oprnd) => {
let exp_inner = unpack_expected(fcx, expected, |sty| {
match unop {
ast::UnBox | ast::UnUniq => match *sty {
ty::ty_box(ty) => Some(ty),
ty::ty_uniq(ref mt) => Some(mt.ty),
_ => None
},
ast::UnNot | ast::UnNeg => expected,
ast::UnDeref => None
ast::UnBox | ast::UnUniq => match *sty {
ty::ty_box(ty) | ty::ty_uniq(ty) => Some(ty),
_ => None
},
ast::UnNot | ast::UnNeg => expected,
ast::UnDeref => None
}
});
check_expr_with_opt_hint(fcx, oprnd, exp_inner);
@ -2824,9 +2821,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
oprnd_t = ty::mk_box(tcx, oprnd_t)
}
ast::UnUniq => {
oprnd_t = ty::mk_uniq(tcx,
ty::mt {ty: oprnd_t,
mutbl: ast::MutImmutable});
oprnd_t = ty::mk_uniq(tcx, oprnd_t);
}
ast::UnDeref => {
let sty = structure_of(fcx, expr.span, oprnd_t);

View File

@ -582,14 +582,14 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: @FnCtxt, is_early: bool) {
let ty = structurally_resolved_type(fcx, ex.span,
fcx.expr_ty(src));
match (&ty::get(ty).sty, store) {
(&ty::ty_box(..), ty::BoxTraitStore)
(&ty::ty_box(..), ty::BoxTraitStore) |
(&ty::ty_uniq(..), ty::UniqTraitStore)
if !mutability_allowed(ast::MutImmutable,
target_mutbl) => {
fcx.tcx().sess.span_err(ex.span,
format!("types differ in mutability"));
}
(&ty::ty_uniq(mt), ty::UniqTraitStore) |
(&ty::ty_rptr(_, mt), ty::RegionTraitStore(..))
if !mutability_allowed(mt.mutbl, target_mutbl) => {
fcx.tcx().sess.span_err(ex.span,
@ -600,8 +600,8 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: @FnCtxt, is_early: bool) {
(&ty::ty_uniq(..), ty::UniqTraitStore) |
(&ty::ty_rptr(..), ty::RegionTraitStore(..)) => {
let typ = match (&ty::get(ty).sty) {
&ty::ty_box(typ) => typ,
&ty::ty_uniq(mt) | &ty::ty_rptr(_, mt) => mt.ty,
&ty::ty_box(typ) | &ty::ty_uniq(typ) => typ,
&ty::ty_rptr(_, mt) => mt.ty,
_ => fail!("shouldn't get here"),
};

View File

@ -245,8 +245,7 @@ impl Coerce {
let r_borrow = self.get_ref().infcx.next_region_var(Coercion(self.get_ref().trace));
let inner_ty = match *sty_a {
ty::ty_box(typ) => typ,
ty::ty_uniq(mt_a) => mt_a.ty,
ty::ty_box(typ) | ty::ty_uniq(typ) => typ,
ty::ty_rptr(_, mt_a) => mt_a.ty,
_ => {
return self.subtype(a, b);

View File

@ -521,8 +521,8 @@ pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
this.tys(a_inner, b_inner).and_then(|typ| Ok(ty::mk_box(tcx, typ)))
}
(&ty::ty_uniq(ref a_mt), &ty::ty_uniq(ref b_mt)) => {
this.mts(a_mt, b_mt).and_then(|mt| Ok(ty::mk_uniq(tcx, mt)))
(&ty::ty_uniq(a_inner), &ty::ty_uniq(b_inner)) => {
this.tys(a_inner, b_inner).and_then(|typ| Ok(ty::mk_uniq(tcx, typ)))
}
(&ty::ty_ptr(ref a_mt), &ty::ty_ptr(ref b_mt)) => {

View File

@ -634,11 +634,10 @@ impl<'a> ConstraintContext<'a> {
self.add_constraints_from_mt(mt, variance);
}
ty::ty_box(typ) => {
ty::ty_uniq(typ) | ty::ty_box(typ) => {
self.add_constraints_from_ty(typ, variance);
}
ty::ty_uniq(ref mt) |
ty::ty_ptr(ref mt) => {
self.add_constraints_from_mt(mt, variance);
}

View File

@ -455,7 +455,7 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str {
ty_uint(t) => ast_util::uint_ty_to_str(t),
ty_float(t) => ast_util::float_ty_to_str(t),
ty_box(typ) => ~"@" + ty_to_str(cx, typ),
ty_uniq(ref tm) => ~"~" + mt_to_str(cx, tm),
ty_uniq(typ) => ~"~" + ty_to_str(cx, typ),
ty_ptr(ref tm) => ~"*" + mt_to_str(cx, tm),
ty_rptr(r, ref tm) => {
region_ptr_to_str(cx, r) + mt_to_str(cx, tm)

View File

@ -377,7 +377,7 @@ pub enum SelfTy {
SelfStatic,
SelfValue,
SelfBorrowed(Option<Lifetime>, Mutability),
SelfManaged(Mutability),
SelfManaged,
SelfOwned,
}
@ -388,7 +388,7 @@ impl Clean<SelfTy> for ast::ExplicitSelf {
ast::SelfValue(_) => SelfValue,
ast::SelfUniq(_) => SelfOwned,
ast::SelfRegion(lt, mt) => SelfBorrowed(lt.clean(), mt.clean()),
ast::SelfBox(mt) => SelfManaged(mt.clean()),
ast::SelfBox => SelfManaged,
}
}
}

View File

@ -405,8 +405,7 @@ impl<'a> fmt::Default for Method<'a> {
clean::SelfStatic => {},
clean::SelfValue => args.push_str("self"),
clean::SelfOwned => args.push_str("~self"),
clean::SelfManaged(clean::Mutable) => args.push_str("@mut self"),
clean::SelfManaged(clean::Immutable) => args.push_str("@self"),
clean::SelfManaged => args.push_str("@self"),
clean::SelfBorrowed(Some(ref lt), clean::Immutable) => {
args.push_str(format!("&amp;{} self", *lt));
}

View File

@ -370,13 +370,13 @@ mod test {
count: 0,
};
// FIXME (#7049): Figure out some other way to do this.
//let buf = @mut ~[8, 9];
//let buf = RefCell::new(~[8, 9]);
(|| {
//reader.push_bytes(&mut *buf, 4);
//reader.push_bytes(buf.borrow_mut().get(), 4);
}).finally(|| {
// NB: Using rtassert here to trigger abort on failure since this is a should_fail test
// FIXME: #7049 This fails because buf is still borrowed
//rtassert!(*buf == ~[8, 9, 10]);
//rtassert!(buf.borrow().get() == ~[8, 9, 10]);
})
}

View File

@ -187,8 +187,7 @@ pub fn get<T: 'static, U>(key: Key<T>, f: |Option<&T>| -> U) -> U {
/// if the key provided is not present in TLS currently.
///
/// It is considered a runtime error to attempt to get a value which is already
/// on loan via this or the `get` methods. This is similar to how it's a runtime
/// error to take two mutable loans on an `@mut` box.
/// on loan via this or the `get` methods.
pub fn get_mut<T: 'static, U>(key: Key<T>, f: |Option<&mut T>| -> U) -> U {
get_with(key, MutLoan, |x| {
match x {

View File

@ -1837,11 +1837,8 @@ impl<T:Eq> OwnedEqVector<T> for ~[T] {
fn dedup(&mut self) {
unsafe {
// Although we have a mutable reference to `self`, we cannot make
// *arbitrary* changes. There exists the possibility that this
// vector is contained with an `@mut` box and hence is still
// readable by the outside world during the `Eq` comparisons.
// Moreover, those comparisons could fail, so we must ensure
// that the vector is in a valid state at all time.
// *arbitrary* changes. The `Eq` comparisons could fail, so we
// must ensure that the vector is in a valid state at all time.
//
// The way that we handle this is by using swaps; we iterate
// over all the elements, swapping as we go so that at the end

View File

@ -959,10 +959,10 @@ pub enum RetStyle {
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
pub enum ExplicitSelf_ {
SelfStatic, // no self
SelfValue(Mutability), // `self`
SelfRegion(Option<Lifetime>, Mutability), // `&'lt self`
SelfBox(Mutability), // `@self`
SelfUniq(Mutability) // `~self`
SelfValue(Mutability), // `self`, `mut self`
SelfRegion(Option<Lifetime>, Mutability), // `&'lt self`, `&'lt mut self`
SelfBox, // `@self`
SelfUniq(Mutability) // `~self`, `mut ~self`
}
pub type ExplicitSelf = Spanned<ExplicitSelf_>;

View File

@ -251,7 +251,7 @@ pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
span,
match *ptr {
Send => ast::SelfUniq(ast::MutImmutable),
Managed => ast::SelfBox(ast::MutImmutable),
Managed => ast::SelfBox,
Borrowed(ref lt, mutbl) => {
let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s)));
ast::SelfRegion(lt, mutbl)

View File

@ -319,7 +319,7 @@ pub trait Folder {
fn fold_explicit_self_(&mut self, es: &ExplicitSelf_) -> ExplicitSelf_ {
match *es {
SelfStatic | SelfValue(_) | SelfUniq(_) | SelfBox(_) => {
SelfStatic | SelfValue(_) | SelfUniq(_) | SelfBox => {
*es
}
SelfRegion(ref lifetime, m) => {

View File

@ -142,8 +142,6 @@ at INTERPOLATED tokens */
macro_rules! maybe_whole_expr (
($p:expr) => (
{
// This horrible convolution is brought to you by
// @mut, have a terrible day
let mut maybe_path = match ($p).token {
INTERPOLATED(token::NtPath(ref pt)) => Some((**pt).clone()),
_ => None,
@ -3647,20 +3645,14 @@ impl Parser {
// that may have a self type.
fn parse_fn_decl_with_self(&mut self, parse_arg_fn: |&mut Parser| -> Arg)
-> (ExplicitSelf, P<FnDecl>) {
fn maybe_parse_explicit_self(cnstr: |v: Mutability| ->
ast::ExplicitSelf_,
fn maybe_parse_explicit_self(explicit_self: ast::ExplicitSelf_,
p: &mut Parser)
-> ast::ExplicitSelf_ {
// We need to make sure it isn't a type
if p.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) ||
((p.look_ahead(1, |t| token::is_keyword(keywords::Const, t)) ||
p.look_ahead(1, |t| token::is_keyword(keywords::Mut, t))) &&
p.look_ahead(2, |t| token::is_keyword(keywords::Self, t))) {
if p.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) {
p.bump();
let mutability = p.parse_mutability();
p.expect_self_ident();
cnstr(mutability)
explicit_self
} else {
SelfStatic
}
@ -3719,55 +3711,47 @@ impl Parser {
// backwards compatible.
let lo = self.span.lo;
let explicit_self = match self.token {
token::BINOP(token::AND) => {
maybe_parse_borrowed_explicit_self(self)
}
token::AT => {
maybe_parse_explicit_self(SelfBox, self)
}
token::TILDE => {
maybe_parse_explicit_self(|mutability| {
if mutability != MutImmutable {
self.span_err(self.last_span,
"mutability declaration not allowed here");
}
SelfUniq(MutImmutable)
}, self)
}
token::IDENT(..) if self.is_self_ident() => {
self.bump();
SelfValue(MutImmutable)
}
token::BINOP(token::STAR) => {
// Possibly "*self" or "*mut self" -- not supported. Try to avoid
// emitting cryptic "unexpected token" errors.
self.bump();
let mutability = if Parser::token_is_mutability(&self.token) {
self.parse_mutability()
} else { MutImmutable };
if self.is_self_ident() {
self.span_err(self.span, "cannot pass self by unsafe pointer");
self.bump();
token::BINOP(token::AND) => {
maybe_parse_borrowed_explicit_self(self)
}
SelfValue(mutability)
}
_ if Parser::token_is_mutability(&self.token) &&
self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) => {
let mutability = self.parse_mutability();
self.expect_self_ident();
SelfValue(mutability)
}
_ if Parser::token_is_mutability(&self.token) &&
self.look_ahead(1, |t| *t == token::TILDE) &&
self.look_ahead(2, |t| token::is_keyword(keywords::Self, t)) => {
let mutability = self.parse_mutability();
self.bump();
self.expect_self_ident();
SelfUniq(mutability)
}
_ => {
SelfStatic
}
token::AT => {
maybe_parse_explicit_self(SelfBox, self)
}
token::TILDE => {
maybe_parse_explicit_self(SelfUniq(MutImmutable), self)
}
token::IDENT(..) if self.is_self_ident() => {
self.bump();
SelfValue(MutImmutable)
}
token::BINOP(token::STAR) => {
// Possibly "*self" or "*mut self" -- not supported. Try to avoid
// emitting cryptic "unexpected token" errors.
self.bump();
let mutability = if Parser::token_is_mutability(&self.token) {
self.parse_mutability()
} else { MutImmutable };
if self.is_self_ident() {
self.span_err(self.span, "cannot pass self by unsafe pointer");
self.bump();
}
SelfValue(mutability)
}
_ if Parser::token_is_mutability(&self.token) &&
self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) => {
let mutability = self.parse_mutability();
self.expect_self_ident();
SelfValue(mutability)
}
_ if Parser::token_is_mutability(&self.token) &&
self.look_ahead(1, |t| *t == token::TILDE) &&
self.look_ahead(2, |t| token::is_keyword(keywords::Self, t)) => {
let mutability = self.parse_mutability();
self.bump();
self.expect_self_ident();
SelfUniq(mutability)
}
_ => SelfStatic
};
// If we parsed a self type, expect a comma before the argument list.

View File

@ -1770,8 +1770,8 @@ pub fn print_explicit_self(s: &mut State, explicit_self: ast::ExplicitSelf_) ->
print_mutability(s, m);
word(&mut s.s, "self");
}
ast::SelfBox(m) => {
word(&mut s.s, "@"); print_mutability(s, m); word(&mut s.s, "self");
ast::SelfBox => {
word(&mut s.s, "@self");
}
}
return true;

View File

@ -175,7 +175,7 @@ fn walk_explicit_self<E: Clone, V: Visitor<E>>(visitor: &mut V,
explicit_self: &ExplicitSelf,
env: E) {
match explicit_self.node {
SelfStatic | SelfValue(_) | SelfBox(_) | SelfUniq(_) => {}
SelfStatic | SelfValue(_) | SelfBox | SelfUniq(_) => {}
SelfRegion(ref lifetime, _) => {
visitor.visit_opt_lifetime_ref(explicit_self.span, lifetime, env)
}

View File

@ -1,4 +1,4 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -11,5 +11,6 @@
struct S;
impl S {
fn f(~mut self) {} //~ ERROR mutability declaration not allowed here
fn f(~mut self) {} //~ ERROR found `self` in ident position
//~^ ERROR expected `:` but found `)`
}