@@ -1795,7 +1795,7 @@ pub impl TypeContents {
1795
1795
}
1796
1796
1797
1797
fn nonowned(_cx: ctxt) -> TypeContents {
1798
- TC_MANAGED + TC_BORROWED_POINTER
1798
+ TC_MANAGED + TC_BORROWED_POINTER + TC_NON_OWNED
1799
1799
}
1800
1800
1801
1801
fn contains_managed(&self) -> bool {
@@ -1849,40 +1849,43 @@ impl ToStr for TypeContents {
1849
1849
}
1850
1850
1851
1851
/// 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 };
1853
1853
1854
1854
/// 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 };
1856
1856
1857
1857
/// 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 };
1859
1859
1860
1860
/// 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 };
1862
1862
1863
1863
/// 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 };
1865
1865
1866
1866
/// Type with a destructor
1867
- static TC_DTOR: TypeContents = TypeContents{bits:0b000000010000 };
1867
+ static TC_DTOR: TypeContents = TypeContents{bits: 0b0000_0001_0000 };
1868
1868
1869
1869
/// Contains a managed value
1870
- static TC_MANAGED: TypeContents = TypeContents{bits:0b000000100000 };
1870
+ static TC_MANAGED: TypeContents = TypeContents{bits: 0b0000_0010_0000 };
1871
1871
1872
1872
/// &mut with any region
1873
- static TC_BORROWED_MUT: TypeContents = TypeContents{bits:0b000001000000 };
1873
+ static TC_BORROWED_MUT: TypeContents = TypeContents{bits: 0b0000_0100_0000 };
1874
1874
1875
1875
/// 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 };
1877
1877
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 };
1880
1880
1881
1881
/// 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};
1883
1886
1884
1887
/// All possible contents.
1885
- static TC_ALL: TypeContents = TypeContents{bits:0b011111111111 };
1888
+ static TC_ALL: TypeContents = TypeContents{bits: 0b0111_1111_1111 };
1886
1889
1887
1890
pub fn type_is_copyable(cx: ctxt, t: ty::t) -> bool {
1888
1891
type_contents(cx, t).is_copy(cx)
@@ -2024,14 +2027,13 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
2024
2027
2025
2028
ty_struct(did, ref substs) => {
2026
2029
let flds = struct_fields(cx, did, substs);
2027
- let flds_tc = flds.foldl(
2030
+ let mut res = flds.foldl(
2028
2031
TC_NONE,
2029
2032
|tc, f| tc + tc_mt(cx, f.mt, cache));
2030
2033
if ty::has_dtor(cx, did) {
2031
- flds_tc + TC_DTOR
2032
- } else {
2033
- flds_tc
2034
+ res += TC_DTOR;
2034
2035
}
2036
+ apply_tc_attr(cx, did, res)
2035
2037
}
2036
2038
2037
2039
ty_tup(ref tys) => {
@@ -2040,7 +2042,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
2040
2042
2041
2043
ty_enum(did, ref substs) => {
2042
2044
let variants = substd_enum_variants(cx, did, substs);
2043
- if variants.is_empty() {
2045
+ let res = if variants.is_empty() {
2044
2046
// we somewhat arbitrary declare that empty enums
2045
2047
// are non-copyable
2046
2048
TC_EMPTY_ENUM
@@ -2050,7 +2052,8 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
2050
2052
*tc,
2051
2053
|tc, arg_ty| *tc + tc_ty(cx, *arg_ty, cache))
2052
2054
})
2053
- }
2055
+ };
2056
+ apply_tc_attr(cx, did, res)
2054
2057
}
2055
2058
2056
2059
ty_param(p) => {
@@ -2110,6 +2113,16 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
2110
2113
mc + tc_ty(cx, mt.ty, cache)
2111
2114
}
2112
2115
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
+
2113
2126
fn borrowed_contents(region: ty::Region,
2114
2127
mutbl: ast::mutability) -> TypeContents
2115
2128
{
@@ -3874,28 +3887,32 @@ pub fn lookup_trait_def(cx: ctxt, did: ast::def_id) -> @ty::TraitDef {
3874
3887
}
3875
3888
}
3876
3889
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 {
3880
3892
if is_local(did) {
3881
3893
match tcx.items.find(&did.node) {
3882
3894
Some(
3883
3895
&ast_map::node_item(@ast::item {
3884
3896
attrs: ref attrs,
3885
3897
_
3886
- }, _)) => attr::attrs_contains_name(*attrs, " packed " ),
3898
+ }, _)) => attr::attrs_contains_name(*attrs, attr ),
3887
3899
_ => tcx.sess.bug(fmt!(" lookup_packed: %? is not an item",
3888
3900
did))
3889
3901
}
3890
3902
} else {
3891
3903
let mut ret = false;
3892
3904
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 );
3894
3906
}
3895
3907
ret
3896
3908
}
3897
3909
}
3898
3910
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
+
3899
3916
// Look up a field ID, whether or not it's local
3900
3917
// Takes a list of type substs in case the struct is generic
3901
3918
pub fn lookup_field_type(tcx: ctxt,
0 commit comments