@@ -1795,7 +1795,7 @@ pub impl TypeContents {
17951795 }
17961796
17971797 fn nonowned(_cx: ctxt) -> TypeContents {
1798- TC_MANAGED + TC_BORROWED_POINTER
1798+ TC_MANAGED + TC_BORROWED_POINTER + TC_NON_OWNED
17991799 }
18001800
18011801 fn contains_managed(&self) -> bool {
@@ -1849,40 +1849,43 @@ impl ToStr for TypeContents {
18491849}
18501850
18511851/// Constant for a type containing nothing of interest.
1852- static TC_NONE: TypeContents = TypeContents{bits:0b0000_00000000 };
1852+ static TC_NONE: TypeContents = TypeContents{bits: 0b0000_0000_0000 };
18531853
18541854/// Contains a borrowed value with a lifetime other than static
1855- static TC_BORROWED_POINTER: TypeContents = TypeContents{bits:0b0000_00000001 };
1855+ static TC_BORROWED_POINTER: TypeContents = TypeContents{bits: 0b0000_0000_0001 };
18561856
18571857/// Contains an owned pointer (~T) but not slice of some kind
1858- static TC_OWNED_POINTER: TypeContents = TypeContents{bits:0b000000000010 };
1858+ static TC_OWNED_POINTER: TypeContents = TypeContents{bits: 0b0000_0000_0010 };
18591859
18601860/// Contains an owned vector ~[] or owned string ~str
1861- static TC_OWNED_VEC: TypeContents = TypeContents{bits:0b000000000100 };
1861+ static TC_OWNED_VEC: TypeContents = TypeContents{bits: 0b0000_0000_0100 };
18621862
18631863/// Contains a ~fn() or a ~Trait, which is non-copyable.
1864- static TC_OWNED_CLOSURE: TypeContents = TypeContents{bits:0b000000001000 };
1864+ static TC_OWNED_CLOSURE: TypeContents = TypeContents{bits: 0b0000_0000_1000 };
18651865
18661866/// Type with a destructor
1867- static TC_DTOR: TypeContents = TypeContents{bits:0b000000010000 };
1867+ static TC_DTOR: TypeContents = TypeContents{bits: 0b0000_0001_0000 };
18681868
18691869/// Contains a managed value
1870- static TC_MANAGED: TypeContents = TypeContents{bits:0b000000100000 };
1870+ static TC_MANAGED: TypeContents = TypeContents{bits: 0b0000_0010_0000 };
18711871
18721872/// &mut with any region
1873- static TC_BORROWED_MUT: TypeContents = TypeContents{bits:0b000001000000 };
1873+ static TC_BORROWED_MUT: TypeContents = TypeContents{bits: 0b0000_0100_0000 };
18741874
18751875/// Mutable content, whether owned or by ref
1876- static TC_MUTABLE: TypeContents = TypeContents{bits:0b000010000000 };
1876+ static TC_MUTABLE: TypeContents = TypeContents{bits: 0b0000_1000_0000 };
18771877
1878- /// Mutable content, whether owned or by ref
1879- static TC_ONCE_CLOSURE: TypeContents = TypeContents{bits:0b000100000000 };
1878+ /// One-shot closure
1879+ static TC_ONCE_CLOSURE: TypeContents = TypeContents{bits: 0b0001_0000_0000 };
18801880
18811881/// An enum with no variants.
1882- static TC_EMPTY_ENUM: TypeContents = TypeContents{bits:0b010000000000};
1882+ static TC_EMPTY_ENUM: TypeContents = TypeContents{bits: 0b0010_0000_0000};
1883+
1884+ /// Contains a type marked with `#[non_owned]`
1885+ static TC_NON_OWNED: TypeContents = TypeContents{bits: 0b0100_0000_0000};
18831886
18841887/// All possible contents.
1885- static TC_ALL: TypeContents = TypeContents{bits:0b011111111111 };
1888+ static TC_ALL: TypeContents = TypeContents{bits: 0b0111_1111_1111 };
18861889
18871890pub fn type_is_copyable(cx: ctxt, t: ty::t) -> bool {
18881891 type_contents(cx, t).is_copy(cx)
@@ -2024,14 +2027,13 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
20242027
20252028 ty_struct(did, ref substs) => {
20262029 let flds = struct_fields(cx, did, substs);
2027- let flds_tc = flds.foldl(
2030+ let mut res = flds.foldl(
20282031 TC_NONE,
20292032 |tc, f| tc + tc_mt(cx, f.mt, cache));
20302033 if ty::has_dtor(cx, did) {
2031- flds_tc + TC_DTOR
2032- } else {
2033- flds_tc
2034+ res += TC_DTOR;
20342035 }
2036+ apply_tc_attr(cx, did, res)
20352037 }
20362038
20372039 ty_tup(ref tys) => {
@@ -2040,7 +2042,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
20402042
20412043 ty_enum(did, ref substs) => {
20422044 let variants = substd_enum_variants(cx, did, substs);
2043- if variants.is_empty() {
2045+ let res = if variants.is_empty() {
20442046 // we somewhat arbitrary declare that empty enums
20452047 // are non-copyable
20462048 TC_EMPTY_ENUM
@@ -2050,7 +2052,8 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
20502052 *tc,
20512053 |tc, arg_ty| *tc + tc_ty(cx, *arg_ty, cache))
20522054 })
2053- }
2055+ };
2056+ apply_tc_attr(cx, did, res)
20542057 }
20552058
20562059 ty_param(p) => {
@@ -2110,6 +2113,16 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
21102113 mc + tc_ty(cx, mt.ty, cache)
21112114 }
21122115
2116+ fn apply_tc_attr(cx: ctxt, did: def_id, mut tc: TypeContents) -> TypeContents {
2117+ if has_attr(cx, did, " mutable") {
2118+ tc += TC_MUTABLE;
2119+ }
2120+ if has_attr(cx, did, " non_owned") {
2121+ tc += TC_NON_OWNED;
2122+ }
2123+ tc
2124+ }
2125+
21132126 fn borrowed_contents(region: ty::Region,
21142127 mutbl: ast::mutability) -> TypeContents
21152128 {
@@ -3874,28 +3887,32 @@ pub fn lookup_trait_def(cx: ctxt, did: ast::def_id) -> @ty::TraitDef {
38743887 }
38753888}
38763889
3877- // Determine whether an item is annotated with #[packed] or not
3878- pub fn lookup_packed(tcx: ctxt,
3879- did: def_id) -> bool {
3890+ /// Determine whether an item is annotated with an attribute
3891+ pub fn has_attr(tcx: ctxt, did: def_id, attr: &str) -> bool {
38803892 if is_local(did) {
38813893 match tcx.items.find(&did.node) {
38823894 Some(
38833895 &ast_map::node_item(@ast::item {
38843896 attrs: ref attrs,
38853897 _
3886- }, _)) => attr::attrs_contains_name(*attrs, " packed " ),
3898+ }, _)) => attr::attrs_contains_name(*attrs, attr ),
38873899 _ => tcx.sess.bug(fmt!(" lookup_packed: %? is not an item",
38883900 did))
38893901 }
38903902 } else {
38913903 let mut ret = false;
38923904 do csearch::get_item_attrs(tcx.cstore, did) |meta_items| {
3893- ret = attr::contains_name(meta_items, " packed " );
3905+ ret = attr::contains_name(meta_items, attr );
38943906 }
38953907 ret
38963908 }
38973909}
38983910
3911+ /// Determine whether an item is annotated with `#[packed]` or not
3912+ pub fn lookup_packed(tcx: ctxt, did: def_id) -> bool {
3913+ has_attr(tcx, did, " packed")
3914+ }
3915+
38993916// Look up a field ID, whether or not it's local
39003917// Takes a list of type substs in case the struct is generic
39013918pub fn lookup_field_type(tcx: ctxt,
0 commit comments