add #[non_owned] and #[mutable] attributes

This commit is contained in:
Daniel Micay 2013-05-05 13:48:32 -04:00
parent 063851ffa1
commit 58c0df2af6

View file

@ -1784,7 +1784,7 @@ pub impl TypeContents {
}
fn nonowned(_cx: ctxt) -> TypeContents {
TC_MANAGED + TC_BORROWED_POINTER
TC_MANAGED + TC_BORROWED_POINTER + TC_NON_OWNED
}
fn contains_managed(&self) -> bool {
@ -1838,40 +1838,43 @@ impl ToStr for TypeContents {
}
/// Constant for a type containing nothing of interest.
static TC_NONE: TypeContents = TypeContents{bits:0b0000_00000000};
static TC_NONE: TypeContents = TypeContents{bits: 0b0000_0000_0000};
/// Contains a borrowed value with a lifetime other than static
static TC_BORROWED_POINTER: TypeContents = TypeContents{bits:0b0000_00000001};
static TC_BORROWED_POINTER: TypeContents = TypeContents{bits: 0b0000_0000_0001};
/// Contains an owned pointer (~T) but not slice of some kind
static TC_OWNED_POINTER: TypeContents = TypeContents{bits:0b000000000010};
static TC_OWNED_POINTER: TypeContents = TypeContents{bits: 0b0000_0000_0010};
/// Contains an owned vector ~[] or owned string ~str
static TC_OWNED_VEC: TypeContents = TypeContents{bits:0b000000000100};
static TC_OWNED_VEC: TypeContents = TypeContents{bits: 0b0000_0000_0100};
/// Contains a ~fn() or a ~Trait, which is non-copyable.
static TC_OWNED_CLOSURE: TypeContents = TypeContents{bits:0b000000001000};
static TC_OWNED_CLOSURE: TypeContents = TypeContents{bits: 0b0000_0000_1000};
/// Type with a destructor
static TC_DTOR: TypeContents = TypeContents{bits:0b000000010000};
static TC_DTOR: TypeContents = TypeContents{bits: 0b0000_0001_0000};
/// Contains a managed value
static TC_MANAGED: TypeContents = TypeContents{bits:0b000000100000};
static TC_MANAGED: TypeContents = TypeContents{bits: 0b0000_0010_0000};
/// &mut with any region
static TC_BORROWED_MUT: TypeContents = TypeContents{bits:0b000001000000};
static TC_BORROWED_MUT: TypeContents = TypeContents{bits: 0b0000_0100_0000};
/// Mutable content, whether owned or by ref
static TC_MUTABLE: TypeContents = TypeContents{bits:0b000010000000};
static TC_MUTABLE: TypeContents = TypeContents{bits: 0b0000_1000_0000};
/// Mutable content, whether owned or by ref
static TC_ONCE_CLOSURE: TypeContents = TypeContents{bits:0b000100000000};
/// One-shot closure
static TC_ONCE_CLOSURE: TypeContents = TypeContents{bits: 0b0001_0000_0000};
/// An enum with no variants.
static TC_EMPTY_ENUM: TypeContents = TypeContents{bits:0b010000000000};
static TC_EMPTY_ENUM: TypeContents = TypeContents{bits: 0b0010_0000_0000};
/// Contains a type marked with `#[non_owned]`
static TC_NON_OWNED: TypeContents = TypeContents{bits: 0b0100_0000_0000};
/// All possible contents.
static TC_ALL: TypeContents = TypeContents{bits:0b011111111111};
static TC_ALL: TypeContents = TypeContents{bits: 0b0111_1111_1111};
pub fn type_is_copyable(cx: ctxt, t: ty::t) -> bool {
type_contents(cx, t).is_copy(cx)
@ -1939,7 +1942,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
let _i = indenter();
let mut result = match get(ty).sty {
let result = match get(ty).sty {
// Scalar and unique types are sendable, constant, and owned
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
ty_bare_fn(_) | ty_ptr(_) => {
@ -2013,14 +2016,19 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
ty_struct(did, ref substs) => {
let flds = struct_fields(cx, did, substs);
let flds_tc = flds.foldl(
let mut res = flds.foldl(
TC_NONE,
|tc, f| tc + tc_mt(cx, f.mt, cache));
if ty::has_dtor(cx, did) {
flds_tc + TC_DTOR
} else {
flds_tc
res += TC_DTOR;
}
if has_attr(cx, did, "mutable") {
res += TC_MUTABLE;
}
if has_attr(cx, did, "non_owned") {
res += TC_NON_OWNED;
}
res
}
ty_tup(ref tys) => {
@ -2029,7 +2037,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
ty_enum(did, ref substs) => {
let variants = substd_enum_variants(cx, did, substs);
if variants.is_empty() {
let mut res = if variants.is_empty() {
// we somewhat arbitrary declare that empty enums
// are non-copyable
TC_EMPTY_ENUM
@ -2039,7 +2047,14 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
*tc,
|tc, arg_ty| *tc + tc_ty(cx, *arg_ty, cache))
})
};
if has_attr(cx, did, "mutable") {
res += TC_MUTABLE;
}
if has_attr(cx, did, "non_owned") {
res += TC_NON_OWNED;
}
res
}
ty_param(p) => {
@ -3841,28 +3856,32 @@ pub fn lookup_trait_def(cx: ctxt, did: ast::def_id) -> @ty::TraitDef {
}
}
// Determine whether an item is annotated with #[packed] or not
pub fn lookup_packed(tcx: ctxt,
did: def_id) -> bool {
/// Determine whether an item is annotated with an attribute
pub fn has_attr(tcx: ctxt, did: def_id, attr: &str) -> bool {
if is_local(did) {
match tcx.items.find(&did.node) {
Some(
&ast_map::node_item(@ast::item {
attrs: ref attrs,
_
}, _)) => attr::attrs_contains_name(*attrs, "packed"),
}, _)) => attr::attrs_contains_name(*attrs, attr),
_ => tcx.sess.bug(fmt!("lookup_packed: %? is not an item",
did))
}
} else {
let mut ret = false;
do csearch::get_item_attrs(tcx.cstore, did) |meta_items| {
ret = attr::contains_name(meta_items, "packed");
ret = attr::contains_name(meta_items, attr);
}
ret
}
}
/// Determine whether an item is annotated with `#[packed]` or not
pub fn lookup_packed(tcx: ctxt, did: def_id) -> bool {
has_attr(tcx, did, "packed")
}
// Look up a field ID, whether or not it's local
// Takes a list of type substs in case the struct is generic
pub fn lookup_field_type(tcx: ctxt,