From 3e63fdc4c9a2b3c4855b54da1ac3a0f672b68a26 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Thu, 28 Jul 2011 13:29:29 -0700 Subject: [PATCH] Thread kinds into the type system. Don't quite activate yet, since it breaks stdlib and snapshot isn't ready to compile modified stdlib. --- src/comp/metadata/tydecode.rs | 13 ++++++++- src/comp/metadata/tyencode.rs | 9 +++++- src/comp/middle/alias.rs | 2 +- src/comp/middle/resolve.rs | 4 +-- src/comp/middle/trans.rs | 12 ++++---- src/comp/middle/ty.rs | 53 ++++++++++++++++++++--------------- src/comp/middle/typeck.rs | 17 ++++++----- src/comp/syntax/ast.rs | 4 +-- src/comp/util/ppaux.rs | 2 +- 9 files changed, 72 insertions(+), 44 deletions(-) diff --git a/src/comp/metadata/tydecode.rs b/src/comp/metadata/tydecode.rs index d0a00c9bf69bb..4c07648c3f5c0 100644 --- a/src/comp/metadata/tydecode.rs +++ b/src/comp/metadata/tydecode.rs @@ -202,7 +202,18 @@ fn parse_ty(st: @pstate, sd: str_def) -> ty::t { st.pos = st.pos + 1u; ret ty::mk_tag(st.tcx, def, params); } - 'p' { ret ty::mk_param(st.tcx, parse_int(st) as uint); } + 'p' { + let k = alt next(st) as char { + 'u' { kind_unique } + 's' { kind_shared } + 'p' { kind_pinned } + c { + log_err "unexpected char in encoded type param: "; + log_err c; fail + } + }; + ret ty::mk_param(st.tcx, parse_int(st) as uint, k); + } '@' { ret ty::mk_box(st.tcx, parse_mt(st, sd)); } '*' { ret ty::mk_ptr(st.tcx, parse_mt(st, sd)); } 'V' { ret ty::mk_vec(st.tcx, parse_mt(st, sd)); } diff --git a/src/comp/metadata/tyencode.rs b/src/comp/metadata/tyencode.rs index be9837c75046d..6227876a7b307 100644 --- a/src/comp/metadata/tyencode.rs +++ b/src/comp/metadata/tyencode.rs @@ -173,7 +173,14 @@ fn enc_sty(w: &ioivec::writer, cx: &@ctxt, st: &ty::sty) { w.write_str(cx.ds(def)); w.write_char('|'); } - ty::ty_param(id) { w.write_char('p'); w.write_str(uint::str(id)); } + ty::ty_param(id,k) { + alt k { + kind_unique. { w.write_str("pu"); } + kind_shared. { w.write_str("ps"); } + kind_pinned. { w.write_str("pp"); } + } + w.write_str(uint::str(id)); + } ty::ty_type. { w.write_char('Y'); } ty::ty_task. { w.write_char('a'); } ty::ty_constr(ty, cs) { diff --git a/src/comp/middle/alias.rs b/src/comp/middle/alias.rs index a7b4d25c40704..f73df36227606 100644 --- a/src/comp/middle/alias.rs +++ b/src/comp/middle/alias.rs @@ -682,7 +682,7 @@ fn ty_can_unsafely_include(cx: &ctx, needle: ty::t, haystack: ty::t, // treated as opaque downstream, and is thus safe unless we // saw mutable fields, in which case the whole thing can be // overwritten. - ty::ty_param(_) { + ty::ty_param(_,_) { ret mut; } _ { ret false; } diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index a9a02b8a88feb..db012eca5dd6b 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -610,7 +610,7 @@ fn def_is_obj_field(d: &def) -> bool { } fn def_is_ty_arg(d: &def) -> bool { - ret alt d { ast::def_ty_arg(_) { true } _ { false } }; + ret alt d { ast::def_ty_arg(_,_) { true } _ { false } }; } fn lookup_in_scope(e: &env, sc: scopes, sp: &span, name: &ident, @@ -710,7 +710,7 @@ fn lookup_in_ty_params(name: &ident, ty_params: &ast::ty_param[]) -> option::t[def] { let i = 0u; for tp: ast::ty_param in ty_params { - if str::eq(tp.ident, name) { ret some(ast::def_ty_arg(i)); } + if str::eq(tp.ident, name) { ret some(ast::def_ty_arg(i,tp.kind)); } i += 1u; } ret none[def]; diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 28308b853eaaa..aa2fdd4f2f519 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -256,7 +256,7 @@ fn type_of_inner(cx: &@crate_ctxt, sp: &span, t: &ty::t) -> TypeRef { ty::ty_var(_) { cx.tcx.sess.span_fatal(sp, "trans::type_of called on ty_var"); } - ty::ty_param(_) { llty = T_i8(); } + ty::ty_param(_, _) { llty = T_i8(); } ty::ty_type. { llty = T_ptr(cx.tydesc_type); } } assert (llty as int != 0); @@ -281,7 +281,7 @@ fn type_of_tag(cx: &@crate_ctxt, sp: &span, did: &ast::def_id, t: &ty::t) -> fn type_of_arg(cx: @local_ctxt, sp: &span, arg: &ty::arg) -> TypeRef { alt ty::struct(cx.ccx.tcx, arg.ty) { - ty::ty_param(_) { + ty::ty_param(_, _) { if arg.mode != ty::mo_val { ret T_typaram_ptr(cx.ccx.tn); } } _ { @@ -581,7 +581,7 @@ fn dynamic_size_of(cx: &@block_ctxt, t: ty::t) -> result { ret rslt(bcx, off); } alt ty::struct(bcx_tcx(cx), t) { - ty::ty_param(p) { + ty::ty_param(p,_) { let szptr = field_of_tydesc(cx, t, false, abi::tydesc_field_size); ret rslt(szptr.bcx, szptr.bcx.build.Load(szptr.val)); } @@ -634,7 +634,7 @@ fn dynamic_size_of(cx: &@block_ctxt, t: ty::t) -> result { fn dynamic_align_of(cx: &@block_ctxt, t: &ty::t) -> result { alt ty::struct(bcx_tcx(cx), t) { - ty::ty_param(p) { + ty::ty_param(p,_) { let aptr = field_of_tydesc(cx, t, false, abi::tydesc_field_align); ret rslt(aptr.bcx, aptr.bcx.build.Load(aptr.val)); } @@ -878,7 +878,7 @@ fn linearize_ty_params(cx: &@block_ctxt, t: &ty::t) -> fn linearizer(r: @rr, t: ty::t) { alt ty::struct(bcx_tcx(r.cx), t) { - ty::ty_param(pid) { + ty::ty_param(pid,_) { let seen: bool = false; for d: uint in r.defs { if d == pid { seen = true; } } if !seen { @@ -7279,7 +7279,7 @@ fn trans_tag_variant(cx: @local_ctxt, tag_id: ast::node_id, let ty_param_substs: ty::t[] = ~[]; i = 0u; for tp: ast::ty_param in ty_params { - ty_param_substs += ~[ty::mk_param(cx.ccx.tcx, i)]; + ty_param_substs += ~[ty::mk_param(cx.ccx.tcx, i, tp.kind)]; i += 1u; } let arg_tys = arg_tys_of_fn(cx.ccx, variant.node.id); diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index fb8f18993b7cf..4e75c730cfb59 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -272,7 +272,7 @@ tag sty { ty_res(def_id, t, t[]); ty_var(int); // type variable - ty_param(uint); // fn/tag type param + ty_param(uint, ast::kind); // fn/tag type param ty_type; ty_native(def_id); @@ -459,7 +459,7 @@ fn mk_raw_ty(cx: &ctxt, st: &sty, in_cname: &option::t[str]) -> @raw_t { ty_task. {/* no-op */ } ty_type. {/* no-op */ } ty_native(_) {/* no-op */ } - ty_param(_) { has_params = true; } + ty_param(_,_) { has_params = true; } ty_var(_) { has_vars = true; } ty_tag(_, tys) { for tt: t in tys { derive_flags_t(cx, has_params, has_vars, tt); } @@ -605,7 +605,9 @@ fn mk_res(cx: &ctxt, did: &ast::def_id, inner: &t, tps: &t[]) -> t { fn mk_var(cx: &ctxt, v: int) -> t { ret gen_ty(cx, ty_var(v)); } -fn mk_param(cx: &ctxt, n: uint) -> t { ret gen_ty(cx, ty_param(n)); } +fn mk_param(cx: &ctxt, n: uint, k: ast::kind) -> t { + ret gen_ty(cx, ty_param(n, k)); +} fn mk_type(cx: &ctxt) -> t { ret idx_type; } @@ -672,14 +674,14 @@ fn walk_ty(cx: &ctxt, walker: ty_walk, ty: t) { for tp: t in tps { walk_ty(cx, walker, tp); } } ty_var(_) {/* no-op */ } - ty_param(_) {/* no-op */ } + ty_param(_,_) {/* no-op */ } } walker(ty); } tag fold_mode { fm_var(fn(int) -> t ); - fm_param(fn(uint) -> t ); + fm_param(fn(uint,ast::kind) -> t ); fm_general(fn(t) -> t ); } @@ -800,8 +802,8 @@ fn fold_ty(cx: &ctxt, fld: fold_mode, ty_0: t) -> t { ty_var(id) { alt fld { fm_var(folder) { ty = folder(id); } _ {/* no-op */ } } } - ty_param(id) { - alt fld { fm_param(folder) { ty = folder(id); } _ {/* no-op */ } } + ty_param(id,k) { + alt fld { fm_param(folder) { ty = folder(id,k); } _ {/* no-op */ } } } } @@ -1118,9 +1120,11 @@ fn type_kind(cx: &ctxt, ty: &t) -> ast::kind { ty_var(_) { fail; } - ty_param(_) { - // FIXME: this should contribute the kind-bound of the typaram, - // when those exist. + ty_param(_,k) { + // FIXME: when you turn this on, the stdlib will break; be sure + // to have a snapshot done that understands kinds before doing so. + + // result = kind::lower_kind(result, k); } ty_constr(t, _) { @@ -1187,7 +1191,7 @@ fn type_has_dynamic_size(cx: &ctxt, ty: &t) -> bool { ret type_has_dynamic_size(cx, sub); } ty_var(_) { fail "ty_var in type_has_dynamic_size()"; } - ty_param(_) { ret true; } + ty_param(_,_) { ret true; } ty_type. { ret false; } ty_native(_) { ret false; } } @@ -1313,7 +1317,7 @@ fn type_owns_heap_mem(cx: &ctxt, ty: &t) -> bool { ty_chan(_) { result = false; } ty_task. { result = false; } ty_var(_) { fail "ty_var in type_owns_heap_mem"; } - ty_param(_) { result = false; } + ty_param(_,_) { result = false; } } cx.owns_heap_mem_cache.insert(ty, result); @@ -1322,7 +1326,7 @@ fn type_owns_heap_mem(cx: &ctxt, ty: &t) -> bool { fn type_param(cx: &ctxt, ty: &t) -> option::t[uint] { alt struct(cx, ty) { - ty_param(id) { ret some(id); } + ty_param(id,_) { ret some(id); } _ {/* fall through */ } } ret none; @@ -1450,7 +1454,7 @@ fn hash_type_structure(st: &sty) -> uint { ret h; } ty_var(v) { ret hash_uint(30u, v as uint); } - ty_param(pid) { ret hash_uint(31u, pid); } + ty_param(pid,_) { ret hash_uint(31u, pid); } ty_type. { ret 32u; } ty_native(did) { ret hash_def(33u, did); } ty_bot. { ret 34u; } @@ -1676,8 +1680,9 @@ fn equal_type_structures(a: &sty, b: &sty) -> bool { ty_var(v_a) { alt b { ty_var(v_b) { ret v_a == v_b; } _ { ret false; } } } - ty_param(pid_a) { - alt b { ty_param(pid_b) { ret pid_a == pid_b; } _ { ret false; } } + ty_param(pid_a,k_a) { + alt b { ty_param(pid_b,k_b) { ret pid_a == pid_b && k_a == k_b; } + _ { ret false; } } } ty_type. { alt b { ty_type. { ret true; } _ { ret false; } } } ty_native(a_id) { @@ -1777,7 +1782,7 @@ fn node_id_to_monotype(cx: &ctxt, id: ast::node_id) -> t { fn count_ty_params(cx: &ctxt, ty: t) -> uint { fn counter(cx: &ctxt, param_indices: @mutable uint[], ty: t) { alt struct(cx, ty) { - ty_param(param_idx) { + ty_param(param_idx,_) { let seen = false; for other_param_idx: uint in *param_indices { if param_idx == other_param_idx { seen = true; } @@ -2333,7 +2338,7 @@ mod unify { _ { ret ures_err(terr_mismatch); } } } - ty::ty_param(_) { ret struct_cmp(cx, expected, actual); } + ty::ty_param(_,_) { ret struct_cmp(cx, expected, actual); } ty::ty_tag(expected_id, expected_tps) { alt struct(cx.tcx, actual) { ty::ty_tag(actual_id, actual_tps) { @@ -2719,7 +2724,7 @@ fn bind_params_in_type(sp: &span, cx: &ctxt, next_ty_var: fn() -> int , let i = 0u; while i < ty_param_count { *param_var_ids += ~[next_ty_var()]; i += 1u; } fn binder(sp: span, cx: ctxt, param_var_ids: @mutable int[], - next_ty_var: fn() -> int , index: uint) -> t { + next_ty_var: fn() -> int , index: uint, kind: ast::kind) -> t { if index < ivec::len(*param_var_ids) { ret mk_var(cx, param_var_ids.(index)); } else { @@ -2728,7 +2733,8 @@ fn bind_params_in_type(sp: &span, cx: &ctxt, next_ty_var: fn() -> int , } let new_typ = fold_ty(cx, - fm_param(bind binder(sp, cx, param_var_ids, next_ty_var, _)), + fm_param(bind binder(sp, cx, param_var_ids, next_ty_var, + _, _)), typ); ret {ids: *param_var_ids, ty: new_typ}; } @@ -2738,11 +2744,12 @@ fn bind_params_in_type(sp: &span, cx: &ctxt, next_ty_var: fn() -> int , // substitions. fn substitute_type_params(cx: &ctxt, substs: &ty::t[], typ: t) -> t { if !type_contains_params(cx, typ) { ret typ; } - fn substituter(cx: ctxt, substs: @ty::t[], idx: uint) -> t { + fn substituter(cx: ctxt, substs: @ty::t[], idx: uint, + kind: ast::kind) -> t { // FIXME: bounds check can fail ret substs.(idx); } - ret fold_ty(cx, fm_param(bind substituter(cx, @substs, _)), typ); + ret fold_ty(cx, fm_param(bind substituter(cx, @substs, _, _)), typ); } fn def_has_ty_params(def: &ast::def) -> bool { @@ -2755,7 +2762,7 @@ fn def_has_ty_params(def: &ast::def) -> bool { ast::def_local(_) { ret false; } ast::def_variant(_, _) { ret true; } ast::def_ty(_) { ret false; } - ast::def_ty_arg(_) { ret false; } + ast::def_ty_arg(_,_) { ret false; } ast::def_binding(_) { ret false; } ast::def_use(_) { ret false; } ast::def_native_ty(_) { ret false; } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 2bd0a7cbbaaf2..e8f0cca2f2594 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -367,7 +367,7 @@ fn ast_ty_to_ty(tcx: &ty::ctxt, getter: &ty_getter, ast_ty: &@ast::ty) -> typ = instantiate(tcx, ast_ty.span, getter, id, path.node.types); } some(ast::def_native_ty(id)) { typ = getter(id).ty; } - some(ast::def_ty_arg(id)) { typ = ty::mk_param(tcx, id); } + some(ast::def_ty_arg(id,k)) { typ = ty::mk_param(tcx, id, k); } some(_) { tcx.sess.span_fatal(ast_ty.span, "found type name used as a variable"); @@ -505,10 +505,13 @@ fn proto_to_ty_proto(proto: &ast::proto) -> ast::proto { mod collect { type ctxt = {tcx: ty::ctxt}; - fn mk_ty_params(cx: &@ctxt, n: uint) -> ty::t[] { + fn mk_ty_params(cx: &@ctxt, atps: &ast::ty_param[]) -> ty::t[] { let tps = ~[]; let i = 0u; - while i < n { tps += ~[ty::mk_param(cx.tcx, i)]; i += 1u; } + for atp: ast::ty_param in atps { + tps += ~[ty::mk_param(cx.tcx, i, atp.kind)]; + i += 1u; + } ret tps; } fn ty_of_fn_decl(cx: &@ctxt, convert: &fn(&@ast::ty) -> ty::t , @@ -667,7 +670,7 @@ mod collect { {count: ivec::len(tps), ty: ty::mk_res(cx.tcx, local_def(it.id), t_arg.ty, - mk_ty_params(cx, ivec::len(tps)))}; + mk_ty_params(cx, tps))}; cx.tcx.tcache.insert(local_def(it.id), t_res); ret t_res; } @@ -676,7 +679,7 @@ mod collect { let ty_param_count = ivec::len[ast::ty_param](tps); - let subtys: ty::t[] = mk_ty_params(cx, ty_param_count); + let subtys: ty::t[] = mk_ty_params(cx, tps); let t = ty::mk_tag(cx.tcx, local_def(it.id), subtys); let tpt = {count: ty_param_count, ty: t}; cx.tcx.tcache.insert(local_def(it.id), tpt); @@ -714,7 +717,7 @@ mod collect { // Create a set of parameter types shared among all the variants. let ty_param_count = ivec::len[ast::ty_param](ty_params); - let ty_param_tys: ty::t[] = mk_ty_params(cx, ty_param_count); + let ty_param_tys: ty::t[] = mk_ty_params(cx, ty_params); for variant: ast::variant in variants { // Nullary tag constructors get turned into constants; n-ary tag // constructors get turned into functions. @@ -820,7 +823,7 @@ mod collect { let t_arg = ty_of_arg(cx, f.decl.inputs.(0)); let t_res = ty::mk_res(cx.tcx, local_def(it.id), t_arg.ty, - mk_ty_params(cx, ivec::len(tps))); + mk_ty_params(cx, tps)); let t_ctor = ty::mk_fn(cx.tcx, ast::proto_fn, ~[t_arg], t_res, ast::return, ~[]); diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs index e09be2b3f3352..1a435f547b133 100644 --- a/src/comp/syntax/ast.rs +++ b/src/comp/syntax/ast.rs @@ -46,7 +46,7 @@ tag def { /* variant */ def_ty(def_id); - def_ty_arg(uint); + def_ty_arg(uint, kind); def_binding(def_id); def_use(def_id); def_native_ty(def_id); @@ -74,7 +74,7 @@ fn def_id_of_def(d: def) -> def_id { def_local(id) { ret id; } def_variant(_, id) { ret id; } def_ty(id) { ret id; } - def_ty_arg(_) { fail; } + def_ty_arg(_,_) { fail; } def_binding(id) { ret id; } def_use(id) { ret id; } def_native_ty(id) { ret id; } diff --git a/src/comp/util/ppaux.rs b/src/comp/util/ppaux.rs index 946ec11401395..fdc71f9357b29 100644 --- a/src/comp/util/ppaux.rs +++ b/src/comp/util/ppaux.rs @@ -130,7 +130,7 @@ fn ty_to_str(cx: &ctxt, typ: &t) -> str { ""; } ty_var(v) { s += ""; } - ty_param(id) { + ty_param(id,_) { s += "'" + str::unsafe_from_bytes([('a' as u8) + (id as u8)]); } _ { s += ty_to_short_str(cx, typ); }