@@ -1784,7 +1784,7 @@ pub impl TypeContents {
1784
1784
}
1785
1785
1786
1786
fn nonowned(_cx: ctxt) -> TypeContents {
1787
- TC_MANAGED + TC_BORROWED_POINTER
1787
+ TC_MANAGED + TC_BORROWED_POINTER + TC_NON_OWNED
1788
1788
}
1789
1789
1790
1790
fn contains_managed(&self) -> bool {
@@ -1838,40 +1838,43 @@ impl ToStr for TypeContents {
1838
1838
}
1839
1839
1840
1840
/// Constant for a type containing nothing of interest.
1841
- static TC_NONE: TypeContents = TypeContents{bits:0b0000_00000000 };
1841
+ static TC_NONE: TypeContents = TypeContents{bits: 0b0000_0000_0000 };
1842
1842
1843
1843
/// Contains a borrowed value with a lifetime other than static
1844
- static TC_BORROWED_POINTER: TypeContents = TypeContents{bits:0b0000_00000001 };
1844
+ static TC_BORROWED_POINTER: TypeContents = TypeContents{bits: 0b0000_0000_0001 };
1845
1845
1846
1846
/// Contains an owned pointer (~T) but not slice of some kind
1847
- static TC_OWNED_POINTER: TypeContents = TypeContents{bits:0b000000000010 };
1847
+ static TC_OWNED_POINTER: TypeContents = TypeContents{bits: 0b0000_0000_0010 };
1848
1848
1849
1849
/// Contains an owned vector ~[] or owned string ~str
1850
- static TC_OWNED_VEC: TypeContents = TypeContents{bits:0b000000000100 };
1850
+ static TC_OWNED_VEC: TypeContents = TypeContents{bits: 0b0000_0000_0100 };
1851
1851
1852
1852
/// Contains a ~fn() or a ~Trait, which is non-copyable.
1853
- static TC_OWNED_CLOSURE: TypeContents = TypeContents{bits:0b000000001000 };
1853
+ static TC_OWNED_CLOSURE: TypeContents = TypeContents{bits: 0b0000_0000_1000 };
1854
1854
1855
1855
/// Type with a destructor
1856
- static TC_DTOR: TypeContents = TypeContents{bits:0b000000010000 };
1856
+ static TC_DTOR: TypeContents = TypeContents{bits: 0b0000_0001_0000 };
1857
1857
1858
1858
/// Contains a managed value
1859
- static TC_MANAGED: TypeContents = TypeContents{bits:0b000000100000 };
1859
+ static TC_MANAGED: TypeContents = TypeContents{bits: 0b0000_0010_0000 };
1860
1860
1861
1861
/// &mut with any region
1862
- static TC_BORROWED_MUT: TypeContents = TypeContents{bits:0b000001000000 };
1862
+ static TC_BORROWED_MUT: TypeContents = TypeContents{bits: 0b0000_0100_0000 };
1863
1863
1864
1864
/// Mutable content, whether owned or by ref
1865
- static TC_MUTABLE: TypeContents = TypeContents{bits:0b000010000000 };
1865
+ static TC_MUTABLE: TypeContents = TypeContents{bits: 0b0000_1000_0000 };
1866
1866
1867
- /// Mutable content, whether owned or by ref
1868
- static TC_ONCE_CLOSURE: TypeContents = TypeContents{bits:0b000100000000 };
1867
+ /// One-shot closure
1868
+ static TC_ONCE_CLOSURE: TypeContents = TypeContents{bits: 0b0001_0000_0000 };
1869
1869
1870
1870
/// An enum with no variants.
1871
- static TC_EMPTY_ENUM: TypeContents = TypeContents{bits:0b010000000000};
1871
+ static TC_EMPTY_ENUM: TypeContents = TypeContents{bits: 0b0010_0000_0000};
1872
+
1873
+ /// Contains a type marked with `#[non_owned]`
1874
+ static TC_NON_OWNED: TypeContents = TypeContents{bits: 0b0100_0000_0000};
1872
1875
1873
1876
/// All possible contents.
1874
- static TC_ALL: TypeContents = TypeContents{bits:0b011111111111 };
1877
+ static TC_ALL: TypeContents = TypeContents{bits: 0b0111_1111_1111 };
1875
1878
1876
1879
pub fn type_is_copyable(cx: ctxt, t: ty::t) -> bool {
1877
1880
type_contents(cx, t).is_copy(cx)
@@ -1939,7 +1942,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
1939
1942
1940
1943
let _i = indenter();
1941
1944
1942
- let mut result = match get(ty).sty {
1945
+ let result = match get(ty).sty {
1943
1946
// Scalar and unique types are sendable, constant, and owned
1944
1947
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
1945
1948
ty_bare_fn(_) | ty_ptr(_) => {
@@ -2013,14 +2016,19 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
2013
2016
2014
2017
ty_struct(did, ref substs) => {
2015
2018
let flds = struct_fields(cx, did, substs);
2016
- let flds_tc = flds.foldl(
2019
+ let mut res = flds.foldl(
2017
2020
TC_NONE,
2018
2021
|tc, f| tc + tc_mt(cx, f.mt, cache));
2019
2022
if ty::has_dtor(cx, did) {
2020
- flds_tc + TC_DTOR
2021
- } else {
2022
- flds_tc
2023
+ res += TC_DTOR;
2024
+ }
2025
+ if has_attr(cx, did, " mutable") {
2026
+ res += TC_MUTABLE;
2023
2027
}
2028
+ if has_attr(cx, did, " non_owned") {
2029
+ res += TC_NON_OWNED;
2030
+ }
2031
+ res
2024
2032
}
2025
2033
2026
2034
ty_tup(ref tys) => {
@@ -2029,7 +2037,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
2029
2037
2030
2038
ty_enum(did, ref substs) => {
2031
2039
let variants = substd_enum_variants(cx, did, substs);
2032
- if variants.is_empty() {
2040
+ let mut res = if variants.is_empty() {
2033
2041
// we somewhat arbitrary declare that empty enums
2034
2042
// are non-copyable
2035
2043
TC_EMPTY_ENUM
@@ -2039,7 +2047,14 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
2039
2047
*tc,
2040
2048
|tc, arg_ty| *tc + tc_ty(cx, *arg_ty, cache))
2041
2049
})
2050
+ };
2051
+ if has_attr(cx, did, " mutable") {
2052
+ res += TC_MUTABLE;
2053
+ }
2054
+ if has_attr(cx, did, " non_owned") {
2055
+ res += TC_NON_OWNED;
2042
2056
}
2057
+ res
2043
2058
}
2044
2059
2045
2060
ty_param(p) => {
@@ -3841,28 +3856,32 @@ pub fn lookup_trait_def(cx: ctxt, did: ast::def_id) -> @ty::TraitDef {
3841
3856
}
3842
3857
}
3843
3858
3844
- // Determine whether an item is annotated with #[packed] or not
3845
- pub fn lookup_packed(tcx: ctxt,
3846
- did: def_id) -> bool {
3859
+ /// Determine whether an item is annotated with an attribute
3860
+ pub fn has_attr(tcx: ctxt, did: def_id, attr: &str) -> bool {
3847
3861
if is_local(did) {
3848
3862
match tcx.items.find(&did.node) {
3849
3863
Some(
3850
3864
&ast_map::node_item(@ast::item {
3851
3865
attrs: ref attrs,
3852
3866
_
3853
- }, _)) => attr::attrs_contains_name(*attrs, " packed " ),
3867
+ }, _)) => attr::attrs_contains_name(*attrs, attr ),
3854
3868
_ => tcx.sess.bug(fmt!(" lookup_packed: %? is not an item",
3855
3869
did))
3856
3870
}
3857
3871
} else {
3858
3872
let mut ret = false;
3859
3873
do csearch::get_item_attrs(tcx.cstore, did) |meta_items| {
3860
- ret = attr::contains_name(meta_items, " packed " );
3874
+ ret = attr::contains_name(meta_items, attr );
3861
3875
}
3862
3876
ret
3863
3877
}
3864
3878
}
3865
3879
3880
+ /// Determine whether an item is annotated with `#[packed]` or not
3881
+ pub fn lookup_packed(tcx: ctxt, did: def_id) -> bool {
3882
+ has_attr(tcx, did, " packed")
3883
+ }
3884
+
3866
3885
// Look up a field ID, whether or not it's local
3867
3886
// Takes a list of type substs in case the struct is generic
3868
3887
pub fn lookup_field_type(tcx: ctxt,
0 commit comments