rustc: Use interior vectors for tag type parameters
This commit is contained in:
parent
111989a626
commit
ede35f4c43
@ -169,8 +169,8 @@ fn parse_ty(@pstate st, str_def sd) -> ty::t {
|
||||
case ('t') {
|
||||
assert (next(st) as char == '[');
|
||||
auto def = parse_def(st, sd);
|
||||
let vec[ty::t] params = [];
|
||||
while (peek(st) as char != ']') { params += [parse_ty(st, sd)]; }
|
||||
let ty::t[] params = ~[];
|
||||
while (peek(st) as char != ']') { params += ~[parse_ty(st, sd)]; }
|
||||
st.pos = st.pos + 1u;
|
||||
ret ty::mk_tag(st.tcx, def, params);
|
||||
}
|
||||
|
@ -879,7 +879,11 @@ fn type_of_inner(&@crate_ctxt cx, &span sp, &ty::t t) -> TypeRef {
|
||||
llty = abs_pair;
|
||||
}
|
||||
case (ty::ty_res(_, ?sub, ?tps)) {
|
||||
auto sub1 = ty::substitute_type_params(cx.tcx, tps, sub);
|
||||
// FIXME: Remove this vec->ivec conversion.
|
||||
auto tps_ivec = ~[];
|
||||
for (ty::t typ in tps) { tps_ivec += ~[typ]; }
|
||||
|
||||
auto sub1 = ty::substitute_type_params(cx.tcx, tps_ivec, sub);
|
||||
ret T_struct([T_i32(), type_of_inner(cx, sp, sub1)]);
|
||||
}
|
||||
case (ty::ty_var(_)) {
|
||||
@ -1240,7 +1244,12 @@ fn simplify_type(&@crate_ctxt ccx, &ty::t typ) -> ty::t {
|
||||
ty::mk_nil(ccx.tcx))]);
|
||||
}
|
||||
case (ty::ty_res(_, ?sub, ?tps)) {
|
||||
auto sub1 = ty::substitute_type_params(ccx.tcx, tps, sub);
|
||||
// FIXME: Remove this vec->ivec conversion.
|
||||
auto tps_ivec = ~[];
|
||||
for (ty::t typ in tps) { tps_ivec += ~[typ]; }
|
||||
|
||||
auto sub1 = ty::substitute_type_params(ccx.tcx, tps_ivec,
|
||||
sub);
|
||||
ret ty::mk_imm_tup(ccx.tcx, ~[ty::mk_int(ccx.tcx),
|
||||
simplify_type(ccx, sub1)]);
|
||||
}
|
||||
@ -1259,36 +1268,35 @@ fn static_size_of_tag(&@crate_ctxt cx, &span sp, &ty::t t) -> uint {
|
||||
"static_size_of_tag()");
|
||||
}
|
||||
if (cx.tag_sizes.contains_key(t)) { ret cx.tag_sizes.get(t); }
|
||||
auto tid;
|
||||
let vec[ty::t] subtys;
|
||||
alt (ty::struct(cx.tcx, t)) {
|
||||
case (ty::ty_tag(?tid_, ?subtys_)) { tid = tid_; subtys = subtys_; }
|
||||
case (ty::ty_tag(?tid, ?subtys)) {
|
||||
// Compute max(variant sizes).
|
||||
|
||||
auto max_size = 0u;
|
||||
auto variants = ty::tag_variants(cx.tcx, tid);
|
||||
for (ty::variant_info variant in variants) {
|
||||
// TODO: Remove this vec->ivec conversion.
|
||||
auto args = ~[];
|
||||
for (ty::t typ in variant.args) { args += ~[typ]; }
|
||||
|
||||
auto tup_ty = simplify_type(cx, ty::mk_imm_tup(cx.tcx, args));
|
||||
// Perform any type parameter substitutions.
|
||||
|
||||
tup_ty = ty::substitute_type_params(cx.tcx, subtys, tup_ty);
|
||||
// Here we possibly do a recursive call.
|
||||
|
||||
auto this_size = llsize_of_real(cx, type_of(cx, sp, tup_ty));
|
||||
if (max_size < this_size) { max_size = this_size; }
|
||||
}
|
||||
cx.tag_sizes.insert(t, max_size);
|
||||
ret max_size;
|
||||
}
|
||||
case (_) {
|
||||
cx.tcx.sess.span_fatal(sp,
|
||||
"non-tag passed to " +
|
||||
"static_size_of_tag()");
|
||||
}
|
||||
}
|
||||
// Compute max(variant sizes).
|
||||
|
||||
auto max_size = 0u;
|
||||
auto variants = ty::tag_variants(cx.tcx, tid);
|
||||
for (ty::variant_info variant in variants) {
|
||||
// TODO: Remove this vec->ivec conversion.
|
||||
auto args = ~[];
|
||||
for (ty::t typ in variant.args) { args += ~[typ]; }
|
||||
|
||||
auto tup_ty = simplify_type(cx, ty::mk_imm_tup(cx.tcx, args));
|
||||
// Perform any type parameter substitutions.
|
||||
|
||||
tup_ty = ty::substitute_type_params(cx.tcx, subtys, tup_ty);
|
||||
// Here we possibly do a recursive call.
|
||||
|
||||
auto this_size = llsize_of_real(cx, type_of(cx, sp, tup_ty));
|
||||
if (max_size < this_size) { max_size = this_size; }
|
||||
}
|
||||
cx.tag_sizes.insert(t, max_size);
|
||||
ret max_size;
|
||||
}
|
||||
|
||||
fn dynamic_size_of(&@block_ctxt cx, ty::t t) -> result {
|
||||
@ -1516,7 +1524,7 @@ fn GEP_tup_like(&@block_ctxt cx, &ty::t t, ValueRef base, &vec[int] ixs) ->
|
||||
// appropriate. @llblobptr is the data part of a tag value; its actual type is
|
||||
// meaningless, as it will be cast away.
|
||||
fn GEP_tag(@block_ctxt cx, ValueRef llblobptr, &ast::def_id tag_id,
|
||||
&ast::def_id variant_id, &vec[ty::t] ty_substs, int ix) -> result {
|
||||
&ast::def_id variant_id, &ty::t[] ty_substs, int ix) -> result {
|
||||
auto variant =
|
||||
ty::tag_variant_with_id(cx.fcx.lcx.ccx.tcx, tag_id, variant_id);
|
||||
// Synthesize a tuple type so that GEP_tup_like() can work its magic.
|
||||
@ -2138,8 +2146,12 @@ fn make_drop_glue(&@block_ctxt cx, ValueRef v0, &ty::t t) {
|
||||
|
||||
fn trans_res_drop(@block_ctxt cx, ValueRef rs, &ast::def_id did,
|
||||
ty::t inner_t, &vec[ty::t] tps) -> result {
|
||||
// FIXME: Remove this vec->ivec conversion.
|
||||
auto tps_ivec = ~[];
|
||||
for (ty::t tp in tps) { tps_ivec += ~[tp]; }
|
||||
|
||||
auto ccx = cx.fcx.lcx.ccx;
|
||||
auto inner_t_s = ty::substitute_type_params(ccx.tcx, tps, inner_t);
|
||||
auto inner_t_s = ty::substitute_type_params(ccx.tcx, tps_ivec, inner_t);
|
||||
auto tup_ty = ty::mk_imm_tup(ccx.tcx, ~[ty::mk_int(ccx.tcx), inner_t_s]);
|
||||
auto drop_cx = new_sub_block_ctxt(cx, "drop res");
|
||||
auto next_cx = new_sub_block_ctxt(cx, "next");
|
||||
@ -2645,7 +2657,7 @@ fn iter_structural_ty_full(&@block_ctxt cx, ValueRef av, ValueRef bv,
|
||||
}
|
||||
|
||||
fn iter_variant(@block_ctxt cx, ValueRef a_tup, ValueRef b_tup,
|
||||
&ty::variant_info variant, &vec[ty::t] tps,
|
||||
&ty::variant_info variant, &ty::t[] tps,
|
||||
&ast::def_id tid, &val_pair_and_ty_fn f) -> result {
|
||||
if (vec::len[ty::t](variant.args) == 0u) {
|
||||
ret rslt(cx, C_nil());
|
||||
@ -2707,8 +2719,12 @@ fn iter_structural_ty_full(&@block_ctxt cx, ValueRef av, ValueRef bv,
|
||||
}
|
||||
}
|
||||
case (ty::ty_res(_, ?inner, ?tps)) {
|
||||
// FIXME: Remove this vec->ivec conversion.
|
||||
auto tps_ivec = ~[];
|
||||
for (ty::t tp in tps) { tps_ivec += ~[tp]; }
|
||||
|
||||
auto inner1 = ty::substitute_type_params(cx.fcx.lcx.ccx.tcx,
|
||||
tps, inner);
|
||||
tps_ivec, inner);
|
||||
r = GEP_tup_like(r.bcx, t, av, [0, 1]);
|
||||
auto llfld_a = r.val;
|
||||
r = GEP_tup_like(r.bcx, t, bv, [0, 1]);
|
||||
@ -4137,8 +4153,12 @@ fn autoderef_lval(&@block_ctxt cx, ValueRef v, &ty::t t, bool is_lval)
|
||||
} else { v1 = body; }
|
||||
}
|
||||
case (ty::ty_res(?did, ?inner, ?tps)) {
|
||||
// FIXME: Remove this vec->ivec conversion.
|
||||
auto tps_ivec = ~[];
|
||||
for (ty::t tp in tps) { tps_ivec += ~[tp]; }
|
||||
|
||||
if (is_lval) { v1 = cx.build.Load(v1); }
|
||||
t1 = ty::substitute_type_params(ccx.tcx, tps, inner);
|
||||
t1 = ty::substitute_type_params(ccx.tcx, tps_ivec, inner);
|
||||
v1 = cx.build.GEP(v1, [C_int(0), C_int(1)]);
|
||||
}
|
||||
case (ty::ty_tag(?did, ?tps)) {
|
||||
@ -4712,14 +4732,19 @@ fn trans_pat_match(&@block_ctxt cx, &@ast::pat pat, ValueRef llval,
|
||||
matched_cx.build.GEP(lltagptr, [C_int(0), C_int(1)]);
|
||||
}
|
||||
}
|
||||
|
||||
auto ty_params = ty::node_id_to_type_params
|
||||
(cx.fcx.lcx.ccx.tcx, pat.id);
|
||||
// FIXME: Remove this vec->ivec conversion.
|
||||
auto tps_ivec = ~[];
|
||||
for (ty::t tp in ty_params) { tps_ivec += ~[tp]; }
|
||||
|
||||
if (vec::len(subpats) > 0u) {
|
||||
auto i = 0;
|
||||
for (@ast::pat subpat in subpats) {
|
||||
auto rslt =
|
||||
GEP_tag(matched_cx, llblobptr, vdef._0, vdef._1,
|
||||
ty_params, i);
|
||||
tps_ivec, i);
|
||||
auto llsubvalptr = rslt.val;
|
||||
matched_cx = rslt.bcx;
|
||||
auto llsubval =
|
||||
@ -4773,14 +4798,19 @@ fn trans_pat_binding(&@block_ctxt cx, &@ast::pat pat, ValueRef llval,
|
||||
(llval, T_opaque_tag_ptr(cx.fcx.lcx.ccx.tn));
|
||||
llblobptr = cx.build.GEP(lltagptr, [C_int(0), C_int(1)]);
|
||||
}
|
||||
|
||||
auto ty_param_substs =
|
||||
ty::node_id_to_type_params(cx.fcx.lcx.ccx.tcx, pat.id);
|
||||
// FIXME: Remove this vec->ivec conversion.
|
||||
auto tps_ivec = ~[];
|
||||
for (ty::t tp in ty_param_substs) { tps_ivec += ~[tp]; }
|
||||
|
||||
auto this_cx = cx;
|
||||
auto i = 0;
|
||||
for (@ast::pat subpat in subpats) {
|
||||
auto rslt =
|
||||
GEP_tag(this_cx, llblobptr, vdef._0, vdef._1,
|
||||
ty_param_substs, i);
|
||||
GEP_tag(this_cx, llblobptr, vdef._0, vdef._1, tps_ivec,
|
||||
i);
|
||||
this_cx = rslt.bcx;
|
||||
auto subpat_res =
|
||||
trans_pat_binding(this_cx, subpat, rslt.val, true);
|
||||
@ -8470,10 +8500,10 @@ fn trans_tag_variant(@local_ctxt cx, ast::node_id tag_id,
|
||||
create_llargs_for_fn_args(fcx, ast::proto_fn, none[ty_self_pair],
|
||||
ty::ret_ty_of_fn(cx.ccx.tcx, variant.node.id),
|
||||
fn_args, ty_params);
|
||||
let vec[ty::t] ty_param_substs = [];
|
||||
let ty::t[] ty_param_substs = ~[];
|
||||
i = 0u;
|
||||
for (ast::ty_param tp in ty_params) {
|
||||
ty_param_substs += [ty::mk_param(cx.ccx.tcx, i)];
|
||||
ty_param_substs += ~[ty::mk_param(cx.ccx.tcx, i)];
|
||||
i += 1u;
|
||||
}
|
||||
auto arg_tys = arg_tys_of_fn(cx.ccx, variant.node.id);
|
||||
|
@ -257,7 +257,7 @@ tag sty {
|
||||
ty_char;
|
||||
ty_str;
|
||||
ty_istr;
|
||||
ty_tag(def_id, vec[t]);
|
||||
ty_tag(def_id, t[]);
|
||||
ty_box(mt);
|
||||
ty_vec(mt);
|
||||
ty_ivec(mt);
|
||||
@ -557,7 +557,7 @@ fn mk_str(&ctxt cx) -> t { ret idx_str; }
|
||||
|
||||
fn mk_istr(&ctxt cx) -> t { ret idx_istr; }
|
||||
|
||||
fn mk_tag(&ctxt cx, &ast::def_id did, &vec[t] tys) -> t {
|
||||
fn mk_tag(&ctxt cx, &ast::def_id did, &t[] tys) -> t {
|
||||
ret gen_ty(cx, ty_tag(did, tys));
|
||||
}
|
||||
|
||||
@ -753,9 +753,9 @@ fn fold_ty(&ctxt cx, fold_mode fld, t ty_0) -> t {
|
||||
ty = copy_cname(cx, mk_chan(cx, fold_ty(cx, fld, subty)), ty);
|
||||
}
|
||||
case (ty_tag(?tid, ?subtys)) {
|
||||
let vec[t] new_subtys = [];
|
||||
let t[] new_subtys = ~[];
|
||||
for (t subty in subtys) {
|
||||
new_subtys += [fold_ty(cx, fld, subty)];
|
||||
new_subtys += ~[fold_ty(cx, fld, subty)];
|
||||
}
|
||||
ty = copy_cname(cx, mk_tag(cx, tid, new_subtys), ty);
|
||||
}
|
||||
@ -1052,8 +1052,12 @@ fn type_has_pointers(&ctxt cx, &t ty) -> bool {
|
||||
}
|
||||
}
|
||||
case (ty_res(?did, ?inner, ?tps)) {
|
||||
// FIXME: Remove this vec->ivec conversion.
|
||||
auto tps_ivec = ~[];
|
||||
for (ty::t tp in tps) { tps_ivec += ~[tp]; }
|
||||
|
||||
result = type_has_pointers
|
||||
(cx, substitute_type_params(cx, tps, inner));
|
||||
(cx, substitute_type_params(cx, tps_ivec, inner));
|
||||
}
|
||||
case (_) { result = true; }
|
||||
}
|
||||
@ -1086,7 +1090,7 @@ fn type_has_dynamic_size(&ctxt cx, &t ty) -> bool {
|
||||
case (ty_istr) { ret false; }
|
||||
case (ty_tag(_, ?subtys)) {
|
||||
auto i = 0u;
|
||||
while (i < vec::len[t](subtys)) {
|
||||
while (i < ivec::len[t](subtys)) {
|
||||
if (type_has_dynamic_size(cx, subtys.(i))) { ret true; }
|
||||
i += 1u;
|
||||
}
|
||||
@ -1240,8 +1244,12 @@ fn type_owns_heap_mem(&ctxt cx, &t ty) -> bool {
|
||||
}
|
||||
}
|
||||
case (ty_res(_, ?inner, ?tps)) {
|
||||
// FIXME: Remove this vec->ivec conversion.
|
||||
auto tps_ivec = ~[];
|
||||
for (ty::t tp in tps) { tps_ivec += ~[tp]; }
|
||||
|
||||
result = type_owns_heap_mem
|
||||
(cx, substitute_type_params(cx, tps, inner));
|
||||
(cx, substitute_type_params(cx, tps_ivec, inner));
|
||||
}
|
||||
|
||||
case (ty_ptr(_)) { result = false; }
|
||||
@ -1272,7 +1280,11 @@ fn type_autoderef(&ctxt cx, &ty::t t) -> ty::t {
|
||||
alt (struct(cx, t1)) {
|
||||
case (ty::ty_box(?mt)) { t1 = mt.ty; }
|
||||
case (ty::ty_res(_, ?inner, ?tps)) {
|
||||
t1 = substitute_type_params(cx, tps, inner);
|
||||
// FIXME: Remove this vec->ivec conversion.
|
||||
auto tps_ivec = ~[];
|
||||
for (ty::t tp in tps) { tps_ivec += ~[tp]; }
|
||||
|
||||
t1 = substitute_type_params(cx, tps_ivec, inner);
|
||||
}
|
||||
case (ty::ty_tag(?did, ?tps)) {
|
||||
auto variants = tag_variants(cx, did);
|
||||
@ -1514,8 +1526,8 @@ fn equal_type_structures(&sty a, &sty b) -> bool {
|
||||
alt (b) {
|
||||
case (ty_tag(?id_b, ?tys_b)) {
|
||||
if (!equal_def(id_a, id_b)) { ret false; }
|
||||
auto len = vec::len[t](tys_a);
|
||||
if (len != vec::len[t](tys_b)) { ret false; }
|
||||
auto len = ivec::len[t](tys_a);
|
||||
if (len != ivec::len[t](tys_b)) { ret false; }
|
||||
auto i = 0u;
|
||||
while (i < len) {
|
||||
if (!eq_ty(tys_a.(i), tys_b.(i))) { ret false; }
|
||||
@ -1755,7 +1767,13 @@ fn ty_param_substs_opt_and_ty_to_monotype(&ctxt cx,
|
||||
t {
|
||||
alt (tpot._0) {
|
||||
case (none) { ret tpot._1; }
|
||||
case (some(?tps)) { ret substitute_type_params(cx, tps, tpot._1); }
|
||||
case (some(?tps)) {
|
||||
// FIXME: Remove this vec->ivec conversion.
|
||||
auto tps_ivec = ~[];
|
||||
for (ty::t tp in tps) { tps_ivec += ~[tp]; }
|
||||
|
||||
ret substitute_type_params(cx, tps_ivec, tpot._1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2328,18 +2346,16 @@ mod unify {
|
||||
// TODO: factor this cruft out, see the TODO in the
|
||||
// ty::ty_tup case
|
||||
|
||||
let vec[t] result_tps = [];
|
||||
let t[] result_tps = ~[];
|
||||
auto i = 0u;
|
||||
auto expected_len = vec::len[t](expected_tps);
|
||||
auto expected_len = ivec::len[t](expected_tps);
|
||||
while (i < expected_len) {
|
||||
auto expected_tp = expected_tps.(i);
|
||||
auto actual_tp = actual_tps.(i);
|
||||
auto result =
|
||||
unify_step(cx, expected_tp, actual_tp);
|
||||
alt (result) {
|
||||
case (ures_ok(?rty)) {
|
||||
vec::push[t](result_tps, rty);
|
||||
}
|
||||
case (ures_ok(?rty)) { result_tps += ~[rty]; }
|
||||
case (_) { ret result; }
|
||||
}
|
||||
i += 1u;
|
||||
@ -2769,14 +2785,13 @@ fn bind_params_in_type(&span sp, &ctxt cx, fn() -> int next_ty_var, t typ,
|
||||
|
||||
// Replaces type parameters in the given type using the given list of
|
||||
// substitions.
|
||||
fn substitute_type_params(&ctxt cx, vec[ty::t] substs, t typ) -> t {
|
||||
fn substitute_type_params(&ctxt cx, &ty::t[] substs, t typ) -> t {
|
||||
if (!type_contains_params(cx, typ)) { ret typ; }
|
||||
fn substituter(ctxt cx, vec[ty::t] substs, uint idx) -> t {
|
||||
fn substituter(ctxt cx, @ty::t[] substs, uint idx) -> 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(&ast::def def) -> bool {
|
||||
|
@ -267,11 +267,11 @@ fn ast_ty_to_ty(&ty::ctxt tcx, &ty_getter getter, &@ast::ty ast_ty) -> ty::t {
|
||||
// The typedef is type-parametric. Do the type substitution.
|
||||
//
|
||||
|
||||
let vec[ty::t] param_bindings = [];
|
||||
let ty::t[] param_bindings = ~[];
|
||||
for (@ast::ty ast_ty in args) {
|
||||
param_bindings += [ast_ty_to_ty(tcx, getter, ast_ty)];
|
||||
param_bindings += ~[ast_ty_to_ty(tcx, getter, ast_ty)];
|
||||
}
|
||||
if (vec::len(param_bindings) !=
|
||||
if (ivec::len(param_bindings) !=
|
||||
ty::count_ty_params(tcx, params_opt_and_ty._1)) {
|
||||
tcx.sess.span_fatal(sp,
|
||||
"Wrong number of type arguments for a" +
|
||||
@ -649,8 +649,13 @@ mod collect {
|
||||
// Create a new generic polytype.
|
||||
|
||||
auto ty_param_count = vec::len[ast::ty_param](tps);
|
||||
|
||||
let vec[ty::t] subtys = mk_ty_params(cx, ty_param_count);
|
||||
auto t = ty::mk_tag(cx.tcx, local_def(it.id), subtys);
|
||||
// FIXME: Remove this vec->ivec conversion.
|
||||
auto tps_ivec = ~[];
|
||||
for (ty::t tp in subtys) { tps_ivec += ~[tp]; }
|
||||
|
||||
auto t = ty::mk_tag(cx.tcx, local_def(it.id), tps_ivec);
|
||||
auto tpt = tup(ty_param_count, t);
|
||||
cx.tcx.tcache.insert(local_def(it.id), tpt);
|
||||
ret tpt;
|
||||
@ -692,9 +697,13 @@ mod collect {
|
||||
// Nullary tag constructors get turned into constants; n-ary tag
|
||||
// constructors get turned into functions.
|
||||
|
||||
// FIXME: Remove this vec->ivec conversion.
|
||||
auto tps_ivec = ~[];
|
||||
for (ty::t tp in ty_param_tys) { tps_ivec += ~[tp]; }
|
||||
|
||||
auto result_ty;
|
||||
if (vec::len[ast::variant_arg](variant.node.args) == 0u) {
|
||||
result_ty = ty::mk_tag(cx.tcx, tag_id, ty_param_tys);
|
||||
result_ty = ty::mk_tag(cx.tcx, tag_id, tps_ivec);
|
||||
} else {
|
||||
// As above, tell ast_ty_to_ty() that trans_ty_item_to_ty()
|
||||
// should be called to resolve named types.
|
||||
@ -705,7 +714,7 @@ mod collect {
|
||||
auto arg_ty = ast_ty_to_ty(cx.tcx, f, va.ty);
|
||||
args += ~[rec(mode=ty::mo_alias(false), ty=arg_ty)];
|
||||
}
|
||||
auto tag_t = ty::mk_tag(cx.tcx, tag_id, ty_param_tys);
|
||||
auto tag_t = ty::mk_tag(cx.tcx, tag_id, tps_ivec);
|
||||
// FIXME: this will be different for constrained types
|
||||
result_ty = ty::mk_fn(cx.tcx, ast::proto_fn, args, tag_t,
|
||||
ast::return, []);
|
||||
@ -861,7 +870,11 @@ fn do_autoderef(&@fn_ctxt fcx, &span sp, &ty::t t) -> ty::t {
|
||||
alt (structure_of(fcx, sp, t1)) {
|
||||
case (ty::ty_box(?inner)) { t1 = inner.ty; }
|
||||
case (ty::ty_res(_, ?inner, ?tps)) {
|
||||
t1 = ty::substitute_type_params(fcx.ccx.tcx, tps, inner);
|
||||
// FIXME: Remove this vec->ivec conversion.
|
||||
auto tps_ivec = ~[];
|
||||
for (ty::t tp in tps) { tps_ivec += ~[tp]; }
|
||||
|
||||
t1 = ty::substitute_type_params(fcx.ccx.tcx, tps_ivec, inner);
|
||||
}
|
||||
case (ty::ty_tag(?did, ?tps)) {
|
||||
auto variants = ty::tag_variants(fcx.ccx.tcx, did);
|
||||
@ -991,7 +1004,7 @@ fn are_compatible(&@fn_ctxt fcx, &ty::t expected, &ty::t actual) -> bool {
|
||||
|
||||
// Returns the types of the arguments to a tag variant.
|
||||
fn variant_arg_types(&@crate_ctxt ccx, &span sp, &ast::def_id vid,
|
||||
&vec[ty::t] tag_ty_params) -> vec[ty::t] {
|
||||
&ty::t[] tag_ty_params) -> vec[ty::t] {
|
||||
let vec[ty::t] result = [];
|
||||
auto tpt = ty::lookup_item_type(ccx.tcx, vid);
|
||||
alt (ty::struct(ccx.tcx, tpt._1)) {
|
||||
@ -1310,67 +1323,60 @@ fn check_pat(&@fn_ctxt fcx, &@ast::pat pat, ty::t expected) {
|
||||
auto path_tpot = instantiate_path(fcx, path, tag_tpt, pat.span);
|
||||
// Take the tag type params out of `expected`.
|
||||
|
||||
auto expected_tps;
|
||||
alt (structure_of(fcx, pat.span, expected)) {
|
||||
case (ty::ty_tag(_, ?tps)) { expected_tps = tps; }
|
||||
case (_) {
|
||||
// FIXME: Switch expected and actual in this message? I
|
||||
// can never tell.
|
||||
case (ty::ty_tag(_, ?expected_tps)) {
|
||||
// Unify with the expected tag type.
|
||||
|
||||
fcx.ccx.tcx.sess.span_fatal(pat.span,
|
||||
#fmt("mismatched types: \
|
||||
expected tag, found %s",
|
||||
ty_to_str(fcx.ccx.tcx,
|
||||
expected)));
|
||||
}
|
||||
}
|
||||
// Unify with the expected tag type.
|
||||
auto ctor_ty =
|
||||
ty::ty_param_substs_opt_and_ty_to_monotype(fcx.ccx.tcx,
|
||||
path_tpot);
|
||||
|
||||
auto ctor_ty =
|
||||
ty::ty_param_substs_opt_and_ty_to_monotype(fcx.ccx.tcx,
|
||||
path_tpot);
|
||||
auto path_tpt =
|
||||
demand::full(fcx, pat.span, expected, ctor_ty, expected_tps,
|
||||
NO_AUTODEREF);
|
||||
path_tpot = tup(some[vec[ty::t]](path_tpt._0), path_tpt._1);
|
||||
// Get the number of arguments in this tag variant.
|
||||
// FIXME: Remove this ivec->vec conversion.
|
||||
auto tps_vec = [];
|
||||
for (ty::t tp in expected_tps) { tps_vec += [tp]; }
|
||||
|
||||
auto arg_types =
|
||||
variant_arg_types(fcx.ccx, pat.span, v_def_ids._1,
|
||||
expected_tps);
|
||||
auto subpats_len = vec::len[@ast::pat](subpats);
|
||||
if (vec::len[ty::t](arg_types) > 0u) {
|
||||
// N-ary variant.
|
||||
auto path_tpt =
|
||||
demand::full(fcx, pat.span, expected, ctor_ty, tps_vec,
|
||||
NO_AUTODEREF);
|
||||
path_tpot = tup(some[vec[ty::t]](path_tpt._0), path_tpt._1);
|
||||
// Get the number of arguments in this tag variant.
|
||||
|
||||
auto arg_len = vec::len[ty::t](arg_types);
|
||||
if (arg_len != subpats_len) {
|
||||
auto arg_types =
|
||||
variant_arg_types(fcx.ccx, pat.span, v_def_ids._1,
|
||||
expected_tps);
|
||||
auto subpats_len = vec::len[@ast::pat](subpats);
|
||||
if (vec::len[ty::t](arg_types) > 0u) {
|
||||
// N-ary variant.
|
||||
|
||||
auto arg_len = vec::len[ty::t](arg_types);
|
||||
if (arg_len != subpats_len) {
|
||||
// TODO: note definition of tag variant
|
||||
// TODO (issue #448): Wrap a #fmt string over multiple
|
||||
// lines...
|
||||
auto s = #fmt("this pattern has %u field%s, but the \
|
||||
corresponding variant has %u field%s",
|
||||
subpats_len,
|
||||
if (subpats_len == 1u) {
|
||||
""
|
||||
} else { "s" }, arg_len,
|
||||
if (arg_len == 1u) {
|
||||
""
|
||||
} else { "s" });
|
||||
fcx.ccx.tcx.sess.span_fatal(pat.span, s);
|
||||
}
|
||||
// TODO: vec::iter2
|
||||
|
||||
auto i = 0u;
|
||||
for (@ast::pat subpat in subpats) {
|
||||
check_pat(fcx, subpat, arg_types.(i));
|
||||
i += 1u;
|
||||
}
|
||||
} else if (subpats_len > 0u) {
|
||||
// TODO: note definition of tag variant
|
||||
// TODO (issue #448): Wrap a #fmt string over multiple
|
||||
// lines...
|
||||
auto s = #fmt("this pattern has %u field%s, but the \
|
||||
corresponding variant has %u field%s",
|
||||
subpats_len,
|
||||
if (subpats_len == 1u) {
|
||||
""
|
||||
} else { "s" }, arg_len,
|
||||
if (arg_len == 1u) {
|
||||
""
|
||||
} else { "s" });
|
||||
fcx.ccx.tcx.sess.span_fatal(pat.span, s);
|
||||
}
|
||||
// TODO: vec::iter2
|
||||
|
||||
auto i = 0u;
|
||||
for (@ast::pat subpat in subpats) {
|
||||
check_pat(fcx, subpat, arg_types.(i));
|
||||
i += 1u;
|
||||
}
|
||||
} else if (subpats_len > 0u) {
|
||||
// TODO: note definition of tag variant
|
||||
// TODO (issue #448): Wrap a #fmt string over multiple
|
||||
// lines...
|
||||
|
||||
fcx.ccx.tcx.sess.span_fatal(pat.span,
|
||||
fcx.ccx.tcx.sess.span_fatal(pat.span,
|
||||
#fmt("this pattern has %u field%s, \
|
||||
but the corresponding \
|
||||
variant has no fields",
|
||||
@ -1378,6 +1384,19 @@ fn check_pat(&@fn_ctxt fcx, &@ast::pat pat, ty::t expected) {
|
||||
if (subpats_len == 1u) {
|
||||
""
|
||||
} else { "s" }));
|
||||
}
|
||||
write::ty_fixup(fcx, pat.id, path_tpot);
|
||||
}
|
||||
case (_) {
|
||||
// FIXME: Switch expected and actual in this message? I
|
||||
// can never tell.
|
||||
|
||||
fcx.ccx.tcx.sess.span_fatal(pat.span,
|
||||
#fmt("mismatched types: \
|
||||
expected tag, found %s",
|
||||
ty_to_str(fcx.ccx.tcx,
|
||||
expected)));
|
||||
}
|
||||
}
|
||||
write::ty_fixup(fcx, pat.id, path_tpot);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import std::io;
|
||||
import std::ivec;
|
||||
import std::vec;
|
||||
import std::str;
|
||||
import std::int;
|
||||
@ -118,9 +119,9 @@ fn ty_to_str(&ctxt cx, &t typ) -> str {
|
||||
// The user should never see this if the cname is set properly!
|
||||
|
||||
s += "<tag#" + int::str(id._0) + ":" + int::str(id._1) + ">";
|
||||
if (vec::len[t](tps) > 0u) {
|
||||
auto f = bind ty_to_str(cx, _);
|
||||
auto strs = vec::map[t, str](f, tps);
|
||||
if (ivec::len[t](tps) > 0u) {
|
||||
let vec[str] strs = [];
|
||||
for (t typ in tps) { strs += [ty_to_str(cx, typ)]; }
|
||||
s += "[" + str::connect(strs, ",") + "]";
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user