diff --git a/src/comp/middle/kind.rs b/src/comp/middle/kind.rs index 3a6d41419f2..e9b15729450 100644 --- a/src/comp/middle/kind.rs +++ b/src/comp/middle/kind.rs @@ -2,6 +2,7 @@ import option::{some, none}; import syntax::{visit, ast_util}; import syntax::ast::*; import syntax::codemap::span; +import ty::{kind, kind_copyable, kind_sendable, kind_noncopyable}; // Kind analysis pass. There are three kinds: // @@ -135,7 +136,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt) { let ty_fields = alt ty::struct(cx.tcx, t) { ty::ty_rec(f) { f } }; for tf in ty_fields { if !vec::any(fields, {|f| f.node.ident == tf.ident}) && - !kind_can_be_copied(ty::type_kind(cx.tcx, tf.mt.ty)) { + !ty::kind_can_be_copied(ty::type_kind(cx.tcx, tf.mt.ty)) { cx.tcx.sess.span_err(ex.span, "copying a noncopyable value"); } @@ -221,13 +222,13 @@ fn check_copy_ex(cx: ctx, ex: @expr, _warn: bool) { } fn check_copy(cx: ctx, ty: ty::t, sp: span) { - if !kind_can_be_copied(ty::type_kind(cx.tcx, ty)) { + if !ty::kind_can_be_copied(ty::type_kind(cx.tcx, ty)) { cx.tcx.sess.span_err(sp, "copying a noncopyable value"); } } fn check_send(cx: ctx, ty: ty::t, sp: span) { - if !kind_can_be_sent(ty::type_kind(cx.tcx, ty)) { + if !ty::kind_can_be_sent(ty::type_kind(cx.tcx, ty)) { cx.tcx.sess.span_err(sp, "not a sendable value"); } } diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index bcc22956a65..bb6d74f232e 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -145,8 +145,8 @@ export ty_fn_args; export type_constr; export type_contains_params; export type_contains_vars; -export kind_lteq; -export type_kind; +export kind, kind_sendable, kind_copyable, kind_noncopyable; +export kind_can_be_copied, kind_can_be_sent, proto_kind, kind_lteq, type_kind; export type_err; export type_err_to_str; export type_has_dynamic_size; @@ -216,7 +216,7 @@ type ctxt = rcache: creader_cache, short_names_cache: hashmap, needs_drop_cache: hashmap, - kind_cache: hashmap, + kind_cache: hashmap, ast_ty_to_ty_cache: hashmap<@ast::ty, option::t>, tag_var_cache: hashmap, iface_method_cache: hashmap, @@ -308,14 +308,14 @@ tag param_bound { bound_iface(t); } -fn param_bounds_to_kind(bounds: @[param_bound]) -> ast::kind { - let kind = ast::kind_noncopyable; +fn param_bounds_to_kind(bounds: @[param_bound]) -> kind { + let kind = kind_noncopyable; for bound in *bounds { alt bound { bound_copy. { - if kind != ast::kind_sendable { kind = ast::kind_copyable; } + if kind != kind_sendable { kind = kind_copyable; } } - bound_send. { kind = ast::kind_sendable; } + bound_send. { kind = kind_sendable; } _ {} } } @@ -847,7 +847,7 @@ fn type_is_structural(cx: ctxt, ty: t) -> bool { } fn type_is_copyable(cx: ctxt, ty: t) -> bool { - ret ast::kind_can_be_copied(type_kind(cx, ty)); + ret kind_can_be_copied(type_kind(cx, ty)); } fn type_is_sequence(cx: ctxt, ty: t) -> bool { @@ -989,6 +989,36 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool { ret result; } +tag kind { kind_sendable; kind_copyable; kind_noncopyable; } + +// 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 } + }; +} + +pure fn kind_can_be_sent(k: kind) -> bool { + ret alt k { + kind_sendable. { true } + kind_copyable. { false } + kind_noncopyable. { false } + }; +} + +fn proto_kind(p: proto) -> kind { + alt p { + ast::proto_block. { kind_noncopyable } + ast::proto_shared(_) { kind_copyable } + ast::proto_send. { kind_sendable } + ast::proto_bare. { kind_sendable } + } +} + fn kind_lteq(a: kind, b: kind) -> bool { alt a { kind_noncopyable. { true } @@ -1001,58 +1031,58 @@ fn lower_kind(a: kind, b: kind) -> kind { if ty::kind_lteq(a, b) { a } else { b } } -fn type_kind(cx: ctxt, ty: t) -> ast::kind { +fn type_kind(cx: ctxt, ty: t) -> kind { alt cx.kind_cache.find(ty) { some(result) { ret result; } none. {/* fall through */ } } // Insert a default in case we loop back on self recursively. - cx.kind_cache.insert(ty, ast::kind_sendable); + cx.kind_cache.insert(ty, kind_sendable); let result = alt struct(cx, ty) { // Scalar and unique types are sendable ty_nil. | ty_bot. | ty_bool. | ty_int(_) | ty_uint(_) | ty_float(_) | ty_native(_) | ty_ptr(_) | - ty_send_type. | ty_str. | ty_native_fn(_, _) { ast::kind_sendable } + ty_send_type. | ty_str. | ty_native_fn(_, _) { kind_sendable } ty_type. { kind_copyable } // FIXME: obj is broken for now, since we aren't asserting // anything about its fields. ty_obj(_) { kind_copyable } - ty_fn(f) { ast::proto_kind(f.proto) } + ty_fn(f) { proto_kind(f.proto) } ty_opaque_closure. { kind_noncopyable } // Those with refcounts-to-inner raise pinned to shared, // lower unique to shared. Therefore just set result to shared. - ty_box(_) | ty_iface(_, _) { ast::kind_copyable } + ty_box(_) | ty_iface(_, _) { kind_copyable } // Boxes and unique pointers raise pinned to shared. ty_vec(tm) | ty_uniq(tm) { type_kind(cx, tm.ty) } // Records lower to the lowest of their members. ty_rec(flds) { - let lowest = ast::kind_sendable; + let lowest = kind_sendable; for f in flds { lowest = lower_kind(lowest, type_kind(cx, f.mt.ty)); } lowest } // Tuples lower to the lowest of their members. ty_tup(tys) { - let lowest = ast::kind_sendable; + let lowest = kind_sendable; for ty in tys { lowest = lower_kind(lowest, type_kind(cx, ty)); } lowest } // Tags lower to the lowest of their variants. ty_tag(did, tps) { - let lowest = ast::kind_sendable; + let lowest = kind_sendable; for variant in *tag_variants(cx, did) { for aty in variant.args { // Perform any type parameter substitutions. let arg_ty = substitute_type_params(cx, tps, aty); lowest = lower_kind(lowest, type_kind(cx, arg_ty)); - if lowest == ast::kind_noncopyable { break; } + if lowest == kind_noncopyable { break; } } } lowest } // Resources are always noncopyable. - ty_res(did, inner, tps) { ast::kind_noncopyable } + ty_res(did, inner, tps) { kind_noncopyable } ty_param(_, bounds) { param_bounds_to_kind(bounds) } ty_constr(t, _) { type_kind(cx, t) } }; @@ -1143,7 +1173,7 @@ fn type_allows_implicit_copy(cx: ctxt, ty: t) -> bool { } _ { false } }; - }) && type_kind(cx, ty) != ast::kind_noncopyable; + }) && type_kind(cx, ty) != kind_noncopyable; } fn type_structurally_contains_uniques(cx: ctxt, ty: t) -> bool { diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs index bc688719b24..04516826ba7 100644 --- a/src/comp/syntax/ast.rs +++ b/src/comp/syntax/ast.rs @@ -110,27 +110,6 @@ tag pat_ { tag mutability { mut; imm; maybe_mut; } -tag kind { kind_sendable; kind_copyable; kind_noncopyable; } - -// 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 } - }; -} - -pure fn kind_can_be_sent(k: kind) -> bool { - ret alt k { - kind_sendable. { true } - kind_copyable. { false } - kind_noncopyable. { false } - }; -} - tag proto_sugar { sugar_normal; sugar_sexy; @@ -143,15 +122,6 @@ tag proto { proto_block; } -fn proto_kind(p: proto) -> kind { - alt p { - ast::proto_block. { ast::kind_noncopyable } - ast::proto_shared(_) { ast::kind_copyable } - ast::proto_send. { ast::kind_sendable } - ast::proto_bare. { ast::kind_sendable } - } -} - tag binop { add; sub;