mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-26 14:43:24 +00:00
auto merge of #11485 : eddyb/rust/sweep-old-rust, r=nikomatsakis
This commit is contained in:
commit
9075025c7b
@ -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])),
|
||||
|
@ -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 ]);
|
||||
|
@ -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));
|
||||
|
@ -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, "&");
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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_));
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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])
|
||||
|
@ -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);
|
||||
|
@ -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)]
|
||||
|
@ -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()),
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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`).
|
||||
|
@ -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]);
|
||||
|
@ -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))
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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, _, _) => {
|
||||
|
@ -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);
|
||||
|
@ -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"),
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)) => {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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!("&{} self", *lt));
|
||||
}
|
||||
|
@ -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]);
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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_>;
|
||||
|
@ -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)
|
||||
|
@ -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) => {
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 `)`
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user