diff --git a/src/rustc/middle/kind.rs b/src/rustc/middle/kind.rs index 999c4390487..e7c318b7da5 100644 --- a/src/rustc/middle/kind.rs +++ b/src/rustc/middle/kind.rs @@ -1,7 +1,7 @@ import syntax::{visit, ast_util}; import syntax::ast::*; import syntax::codemap::span; -import ty::{kind, kind_copyable, kind_sendable, kind_noncopyable}; +import ty::{kind, kind_sendable, kind_copyable, kind_noncopyable }; import driver::session::session; import std::map::hashmap; import util::ppaux::{ty_to_str, tys_to_str}; @@ -24,11 +24,10 @@ import freevars::freevar_entry; // types. fn kind_to_str(k: kind) -> str { - alt k { - kind_sendable { "sendable" } - kind_copyable { "copyable" } - kind_noncopyable { "noncopyable" } - } + if k == kind_sendable() { "sendable" } + else if k == kind_copyable() { "copyable" } + else if k == kind_noncopyable() { "noncopyable" } + else { fail "unknown kind" } } type rval_map = std::map::hashmap; diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index 6d0362882fe..998dc9d5951 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -421,13 +421,13 @@ impl of vid for region_vid { } fn param_bounds_to_kind(bounds: param_bounds) -> kind { - let mut kind = kind_noncopyable; + let mut kind = kind_noncopyable(); for vec::each(*bounds) {|bound| alt bound { bound_copy { - if kind != kind_sendable { kind = kind_copyable; } + if kind != kind_sendable() { kind = kind_copyable(); } } - bound_send { kind = kind_sendable; } + bound_send { kind = kind_sendable(); } _ {} } } @@ -1260,43 +1260,46 @@ fn type_needs_unwind_cleanup_(cx: ctxt, ty: t, ret needs_unwind_cleanup; } -enum kind { kind_sendable, kind_copyable, kind_noncopyable, } +enum kind { kind_(u32) } + +const KIND_MASK_COPY : u32 = 0b00000000000000000000000000000001u32; +const KIND_MASK_SEND : u32 = 0b00000000000000000000000000000010u32; + +fn kind_noncopyable() -> kind { + kind_(0u32) +} + +fn kind_copyable() -> kind { + kind_(KIND_MASK_COPY) +} + +fn kind_sendable() -> kind { + kind_(KIND_MASK_COPY | KIND_MASK_SEND) +} // Using these query functons is preferable to direct comparison or matching // against the kind constants, as we may modify the kind hierarchy in the // future. pure fn kind_can_be_copied(k: kind) -> bool { - ret alt k { - kind_sendable { true } - kind_copyable { true } - kind_noncopyable { false } - }; + *k & KIND_MASK_COPY != 0u32 } pure fn kind_can_be_sent(k: kind) -> bool { - ret alt k { - kind_sendable { true } - kind_copyable { false } - kind_noncopyable { false } - }; + *k & KIND_MASK_SEND != 0u32 } fn proto_kind(p: proto) -> kind { alt p { - ast::proto_any { kind_noncopyable } - ast::proto_block { kind_noncopyable } - ast::proto_box { kind_copyable } - ast::proto_uniq { kind_sendable } - ast::proto_bare { kind_sendable } + ast::proto_any { kind_noncopyable() } + ast::proto_block { kind_noncopyable() } + ast::proto_box { kind_copyable() } + ast::proto_uniq { kind_sendable() } + ast::proto_bare { kind_sendable() } } } fn kind_lteq(a: kind, b: kind) -> bool { - alt a { - kind_noncopyable { true } - kind_copyable { b != kind_noncopyable } - kind_sendable { b == kind_sendable } - } + *a & *b == *a } fn lower_kind(a: kind, b: kind) -> kind { @@ -1306,12 +1309,12 @@ fn lower_kind(a: kind, b: kind) -> kind { #[test] fn test_kinds() { // The kind "lattice" is nocopy <= copy <= send - assert kind_lteq(kind_sendable, kind_sendable); - assert kind_lteq(kind_copyable, kind_sendable); - assert kind_lteq(kind_copyable, kind_copyable); - assert kind_lteq(kind_noncopyable, kind_sendable); - assert kind_lteq(kind_noncopyable, kind_copyable); - assert kind_lteq(kind_noncopyable, kind_noncopyable); + assert kind_lteq(kind_sendable(), kind_sendable()); + assert kind_lteq(kind_copyable(), kind_sendable()); + assert kind_lteq(kind_copyable(), kind_copyable()); + assert kind_lteq(kind_noncopyable(), kind_sendable()); + assert kind_lteq(kind_noncopyable(), kind_copyable()); + assert kind_lteq(kind_noncopyable(), kind_noncopyable()); } fn type_kind(cx: ctxt, ty: t) -> kind { @@ -1321,24 +1324,24 @@ fn type_kind(cx: ctxt, ty: t) -> kind { } // Insert a default in case we loop back on self recursively. - cx.kind_cache.insert(ty, kind_sendable); + cx.kind_cache.insert(ty, kind_sendable()); let result = alt get(ty).struct { // Scalar and unique types are sendable ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) | - ty_ptr(_) | ty_str { kind_sendable } - ty_type { kind_copyable } + ty_ptr(_) | ty_str { kind_sendable() } + ty_type { kind_copyable() } ty_fn(f) { proto_kind(f.proto) } // Closures have kind determined by capture mode - ty_opaque_closure_ptr(ck_block) { kind_noncopyable } - ty_opaque_closure_ptr(ck_box) { kind_copyable } - ty_opaque_closure_ptr(ck_uniq) { kind_sendable } + ty_opaque_closure_ptr(ck_block) { kind_noncopyable() } + ty_opaque_closure_ptr(ck_box) { kind_copyable() } + ty_opaque_closure_ptr(ck_uniq) { kind_sendable() } // Those with refcounts raise noncopyable to copyable, // lower sendable to copyable. Therefore just set result to copyable. - ty_box(_) | ty_iface(_, _) | ty_opaque_box { kind_copyable } - ty_rptr(_, _) { kind_copyable } + ty_box(_) | ty_iface(_, _) | ty_opaque_box { kind_copyable() } + ty_rptr(_, _) { kind_copyable() } // Unique boxes and vecs have the kind of their contained type. ty_vec(tm) | ty_uniq(tm) { type_kind(cx, tm.ty) } @@ -1346,19 +1349,19 @@ fn type_kind(cx: ctxt, ty: t) -> kind { // Slice and refcounted evecs are copyable; uniques and interiors // depend on the their contained type. ty_evec(_, vstore_box) | - ty_evec(_, vstore_slice(_)) { kind_copyable } + ty_evec(_, vstore_slice(_)) { kind_copyable() } ty_evec(tm, vstore_uniq) | ty_evec(tm, vstore_fixed(_)) { type_kind(cx, tm.ty) } // All estrs are copyable; uniques and interiors are sendable. ty_estr(vstore_box) | - ty_estr(vstore_slice(_)) { kind_copyable } + ty_estr(vstore_slice(_)) { kind_copyable() } ty_estr(vstore_uniq) | - ty_estr(vstore_fixed(_)) { kind_sendable } + ty_estr(vstore_fixed(_)) { kind_sendable() } // Records lower to the lowest of their members. ty_rec(flds) { - let mut lowest = kind_sendable; + let mut lowest = kind_sendable(); for flds.each {|f| lowest = lower_kind(lowest, type_kind(cx, f.mt.ty)); } @@ -1368,7 +1371,7 @@ fn type_kind(cx: ctxt, ty: t) -> kind { // sendable, but I'm just treating them like records (#1726) ty_class(did, substs) { // also factor out this code, copied from the records case - let mut lowest = kind_sendable; + let mut lowest = kind_sendable(); let flds = class_items_as_fields(cx, did, substs); for flds.each {|f| lowest = lower_kind(lowest, type_kind(cx, f.mt.ty)); @@ -1377,34 +1380,34 @@ fn type_kind(cx: ctxt, ty: t) -> kind { } // Tuples lower to the lowest of their members. ty_tup(tys) { - let mut lowest = kind_sendable; + let mut lowest = kind_sendable(); for tys.each {|ty| lowest = lower_kind(lowest, type_kind(cx, ty)); } lowest } // Enums lower to the lowest of their variants. ty_enum(did, substs) { - let mut lowest = kind_sendable; + let mut lowest = kind_sendable(); let variants = enum_variants(cx, did); if vec::len(*variants) == 0u { - lowest = kind_noncopyable; + lowest = kind_noncopyable(); } else { for vec::each(*variants) {|variant| for variant.args.each {|aty| // Perform any type parameter substitutions. let arg_ty = subst(cx, substs, aty); lowest = lower_kind(lowest, type_kind(cx, arg_ty)); - if lowest == kind_noncopyable { break; } + if lowest == kind_noncopyable() { break; } } } } lowest } - ty_res(did, inner, tps) { kind_noncopyable } + ty_res(did, inner, tps) { kind_noncopyable() } ty_param(_, did) { param_bounds_to_kind(cx.ty_param_bounds.get(did.node)) } ty_constr(t, _) { type_kind(cx, t) } - ty_self { kind_noncopyable } + ty_self { kind_noncopyable() } ty_var(_) { cx.sess.bug("Asked to compute kind of a type variable"); } }; @@ -1605,7 +1608,7 @@ fn type_allows_implicit_copy(cx: ctxt, ty: t) -> bool { } _ { false } } - }) && type_kind(cx, ty) != kind_noncopyable; + }) && type_kind(cx, ty) != kind_noncopyable(); } fn type_structurally_contains_uniques(cx: ctxt, ty: t) -> bool {