diff --git a/src/comp/metadata/tydecode.rs b/src/comp/metadata/tydecode.rs index b40a84ec305..052af38c151 100644 --- a/src/comp/metadata/tydecode.rs +++ b/src/comp/metadata/tydecode.rs @@ -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); } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 77ffdd1be3a..b6d34c39ddc 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -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); diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 5ef38434e5d..5ab7aafce98 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -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 { diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index b7a8e70b701..ef3eb985947 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -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); } diff --git a/src/comp/util/ppaux.rs b/src/comp/util/ppaux.rs index e3eb707dbf5..58ed9b6157c 100644 --- a/src/comp/util/ppaux.rs +++ b/src/comp/util/ppaux.rs @@ -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 += ""; - 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, ",") + "]"; } }