@@ -1808,6 +1808,15 @@ pub impl TypeContents {
1808
1808
if cx.vecs_implicitly_copyable {base} else {base + TC_OWNED_VEC}
1809
1809
}
1810
1810
1811
+ fn is_safe_for_default_mode(&self, cx: ctxt) -> bool {
1812
+ !self.intersects(TypeContents::nondefault_mode(cx))
1813
+ }
1814
+
1815
+ fn nondefault_mode(cx: ctxt) -> TypeContents {
1816
+ let tc = TypeContents::nonimplicitly_copyable(cx);
1817
+ tc + TC_BIG + TC_OWNED_VEC // disregard cx.vecs_implicitly_copyable
1818
+ }
1819
+
1811
1820
fn needs_drop(&self, cx: ctxt) -> bool {
1812
1821
let tc = TC_MANAGED + TC_DTOR + TypeContents::owned(cx);
1813
1822
self.intersects(tc)
@@ -1867,6 +1876,9 @@ static TC_MUTABLE: TypeContents = TypeContents{bits:0b000010000000};
1867
1876
/// Mutable content, whether owned or by ref
1868
1877
static TC_ONCE_CLOSURE: TypeContents = TypeContents{bits:0b000100000000};
1869
1878
1879
+ /// Something we estimate to be " big"
1880
+ static TC_BIG: TypeContents = TypeContents{bits:0b001000000000};
1881
+
1870
1882
/// An enum with no variants.
1871
1883
static TC_EMPTY_ENUM: TypeContents = TypeContents{bits:0b010000000000};
1872
1884
@@ -2087,6 +2099,10 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
2087
2099
}
2088
2100
};
2089
2101
2102
+ if type_size(cx, ty) > 4 {
2103
+ result = result + TC_BIG;
2104
+ }
2105
+
2090
2106
cache.insert(ty_id, result);
2091
2107
return result;
2092
2108
}
@@ -2162,6 +2178,68 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
2162
2178
debug!(" result = %s", r.to_str());
2163
2179
return r;
2164
2180
}
2181
+
2182
+ /// gives a rough estimate of how much space it takes to represent
2183
+ /// an instance of `ty`. Used for the mode transition.
2184
+ fn type_size(cx: ctxt, ty: t) -> uint {
2185
+ match get(ty).sty {
2186
+ ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
2187
+ ty_ptr(_) | ty_box(_) | ty_uniq(_) | ty_estr(vstore_uniq) |
2188
+ ty_trait(*) | ty_rptr(*) | ty_evec(_, vstore_uniq) |
2189
+ ty_evec(_, vstore_box) | ty_estr(vstore_box) => {
2190
+ 1
2191
+ }
2192
+
2193
+ ty_evec(_, vstore_slice(_)) |
2194
+ ty_estr(vstore_slice(_)) |
2195
+ ty_bare_fn(*) |
2196
+ ty_closure(*) => {
2197
+ 2
2198
+ }
2199
+
2200
+ ty_evec(t, vstore_fixed(n)) => {
2201
+ type_size(cx, t.ty) * n
2202
+ }
2203
+
2204
+ ty_estr(vstore_fixed(n)) => {
2205
+ n
2206
+ }
2207
+
2208
+ ty_struct(did, ref substs) => {
2209
+ let flds = struct_fields(cx, did, substs);
2210
+ flds.foldl(0, |s, f| *s + type_size(cx, f.mt.ty))
2211
+ }
2212
+
2213
+ ty_tup(ref tys) => {
2214
+ tys.foldl(0, |s, t| *s + type_size(cx, *t))
2215
+ }
2216
+
2217
+ ty_enum(did, ref substs) => {
2218
+ let variants = substd_enum_variants(cx, did, substs);
2219
+ variants.foldl( // find max size of any variant
2220
+ 0,
2221
+ |m, v| uint::max(
2222
+ *m,
2223
+ // find size of this variant:
2224
+ v.args.foldl(0, |s, a| *s + type_size(cx, *a))))
2225
+ }
2226
+
2227
+ ty_param(_) | ty_self(_) => {
2228
+ 1
2229
+ }
2230
+
2231
+ ty_infer(_) => {
2232
+ cx.sess.bug(~" Asked to compute kind of a type variable");
2233
+ }
2234
+ ty_type => 1,
2235
+ ty_opaque_closure_ptr(_) => 1,
2236
+ ty_opaque_box => 1,
2237
+ ty_unboxed_vec(_) => 10,
2238
+ ty_err => {
2239
+ cx.sess.bug(~" Asked to compute kind of fictitious type ");
2240
+ }
2241
+ }
2242
+ }
2165
2243
}
2166
2244
2167
2245
pub fn type_moves_by_default(cx: ctxt, ty: t) -> bool {
@@ -2421,15 +2499,12 @@ pub fn type_is_enum(ty: t) -> bool {
2421
2499
// constructors
2422
2500
pub fn type_is_c_like_enum(cx: ctxt, ty: t) -> bool {
2423
2501
match get(ty).sty {
2424
- ty_enum(did, _) => {
2425
- let variants = enum_variants(cx, did);
2426
- if variants.len() == 0 {
2427
- false
2428
- } else {
2429
- variants.all(|v| v.args.len() == 0)
2430
- }
2431
- }
2432
- _ => false
2502
+ ty_enum(did, _) => {
2503
+ let variants = enum_variants(cx, did);
2504
+ let some_n_ary = vec::any(*variants, |v| vec::len(v.args) > 0u);
2505
+ return !some_n_ary;
2506
+ }
2507
+ _ => return false
2433
2508
}
2434
2509
}
2435
2510
0 commit comments