mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-30 10:45:18 +00:00
rustc: Have tag patterns use the type parameter information from the typechecker instead of trying to deduce it in trans. Un-XFAIL test/run-pass/generic-tag-values.rs.
This commit is contained in:
parent
bafcbb101c
commit
874e8e3505
@ -453,7 +453,6 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \
|
||||
foreach-put-structured.rs \
|
||||
foreach-simple-outer-slot.rs \
|
||||
generic-iter-frame.rs \
|
||||
generic-tag-values.rs \
|
||||
iter-range.rs \
|
||||
iter-ret.rs \
|
||||
lazychan.rs \
|
||||
|
@ -1185,8 +1185,16 @@ fn GEP_tup_like(@block_ctxt cx, @ty.t t,
|
||||
// This function uses GEP_tup_like() above and automatically performs casts as
|
||||
// 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.variant variant, int ix)
|
||||
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 {
|
||||
auto ty_params = tag_ty_params(cx.fcx.ccx, tag_id);
|
||||
auto variant = tag_variant_with_id(cx.fcx.ccx, tag_id, variant_id);
|
||||
|
||||
// Synthesize a tuple type so that GEP_tup_like() can work its magic.
|
||||
// Separately, store the type of the element we're interested in.
|
||||
auto arg_tys = arg_tys_of_fn(variant.ann);
|
||||
@ -1194,9 +1202,10 @@ fn GEP_tag(@block_ctxt cx, ValueRef llblobptr, &ast.variant variant, int ix)
|
||||
auto i = 0;
|
||||
let vec[@ty.t] true_arg_tys = vec();
|
||||
for (ty.arg a in arg_tys) {
|
||||
true_arg_tys += vec(a.ty);
|
||||
auto arg_ty = ty.substitute_ty_params(ty_params, ty_substs, a.ty);
|
||||
true_arg_tys += vec(arg_ty);
|
||||
if (i == ix) {
|
||||
elem_ty = a.ty;
|
||||
elem_ty = arg_ty;
|
||||
}
|
||||
|
||||
i += 1;
|
||||
@ -2283,6 +2292,24 @@ fn node_ann_type(@crate_ctxt cx, &ast.ann a) -> @ty.t {
|
||||
}
|
||||
}
|
||||
|
||||
fn node_ann_ty_params(&ast.ann a) -> vec[@ty.t] {
|
||||
alt (a) {
|
||||
case (ast.ann_none) {
|
||||
log "missing type annotation";
|
||||
fail;
|
||||
}
|
||||
case (ast.ann_type(_, ?tps_opt)) {
|
||||
alt (tps_opt) {
|
||||
case (none[vec[@ty.t]]) {
|
||||
log "type annotation has no ty params";
|
||||
fail;
|
||||
}
|
||||
case (some[vec[@ty.t]](?tps)) { ret tps; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn node_type(@crate_ctxt cx, &ast.ann a) -> TypeRef {
|
||||
ret type_of(cx, node_ann_type(cx, a));
|
||||
}
|
||||
@ -2981,13 +3008,15 @@ fn trans_pat_match(@block_ctxt cx, @ast.pat pat, ValueRef llval,
|
||||
C_int(variant_tag));
|
||||
cx.build.CondBr(lleq, matched_cx.llbb, next_cx.llbb);
|
||||
|
||||
auto ty_params = node_ann_ty_params(ann);
|
||||
|
||||
if (_vec.len[@ast.pat](subpats) > 0u) {
|
||||
auto llblobptr = matched_cx.build.GEP(lltagptr,
|
||||
vec(C_int(0), C_int(1)));
|
||||
auto i = 0;
|
||||
for (@ast.pat subpat in subpats) {
|
||||
auto rslt = GEP_tag(matched_cx, llblobptr, variants.(i),
|
||||
i);
|
||||
auto rslt = GEP_tag(matched_cx, llblobptr, vdef._0,
|
||||
vdef._1, ty_params, i);
|
||||
auto llsubvalptr = rslt.val;
|
||||
matched_cx = rslt.bcx;
|
||||
|
||||
@ -3025,7 +3054,7 @@ fn trans_pat_binding(@block_ctxt cx, @ast.pat pat, ValueRef llval)
|
||||
|
||||
ret copy_ty(bcx, INIT, dst, llval, ty);
|
||||
}
|
||||
case (ast.pat_tag(_, ?subpats, ?vdef_opt, _)) {
|
||||
case (ast.pat_tag(_, ?subpats, ?vdef_opt, ?ann)) {
|
||||
if (_vec.len[@ast.pat](subpats) == 0u) { ret res(cx, llval); }
|
||||
|
||||
// Get the appropriate variant for this tag.
|
||||
@ -3036,10 +3065,13 @@ fn trans_pat_binding(@block_ctxt cx, @ast.pat pat, ValueRef llval)
|
||||
T_opaque_tag_ptr(cx.fcx.ccx.tn));
|
||||
auto llblobptr = cx.build.GEP(lltagptr, vec(C_int(0), C_int(1)));
|
||||
|
||||
auto ty_param_substs = node_ann_ty_params(ann);
|
||||
|
||||
auto this_cx = cx;
|
||||
auto i = 0;
|
||||
for (@ast.pat subpat in subpats) {
|
||||
auto rslt = GEP_tag(this_cx, llblobptr, variant, i);
|
||||
auto rslt = GEP_tag(this_cx, llblobptr, vdef._0, vdef._1,
|
||||
ty_param_substs, i);
|
||||
this_cx = rslt.bcx;
|
||||
auto llsubvalptr = rslt.val;
|
||||
|
||||
@ -4926,6 +4958,11 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
|
||||
none[TypeRef], ret_ty_of_fn(variant.ann),
|
||||
fn_args, ty_params);
|
||||
|
||||
let vec[@ty.t] ty_param_substs = vec();
|
||||
for (ast.ty_param tp in ty_params) {
|
||||
ty_param_substs += vec(plain_ty(ty.ty_param(tp.id)));
|
||||
}
|
||||
|
||||
auto bcx = new_top_block_ctxt(fcx);
|
||||
|
||||
auto arg_tys = arg_tys_of_fn(variant.ann);
|
||||
@ -4944,7 +4981,8 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
|
||||
|
||||
i = 0u;
|
||||
for (ast.variant_arg va in variant.args) {
|
||||
auto rslt = GEP_tag(bcx, llblobptr, variant, i as int);
|
||||
auto rslt = GEP_tag(bcx, llblobptr, tag_id, variant.id,
|
||||
ty_param_substs, i as int);
|
||||
bcx = rslt.bcx;
|
||||
auto lldestptr = rslt.val;
|
||||
|
||||
|
@ -1085,6 +1085,7 @@ fn demand_pat(&@fn_ctxt fcx, @ty.t expected, @ast.pat pat) -> @ast.pat {
|
||||
fail;
|
||||
}
|
||||
}
|
||||
auto tps_opt = some[vec[@ty.t]](ty_param_substs);
|
||||
|
||||
// The type of the tag isn't enough; we also have to get the type
|
||||
// of the variant, which is either a tag type in the case of
|
||||
@ -1100,7 +1101,7 @@ fn demand_pat(&@fn_ctxt fcx, @ty.t expected, @ast.pat pat) -> @ast.pat {
|
||||
// Nullary tag variant.
|
||||
check (subpats_len == 0u);
|
||||
p_1 = ast.pat_tag(id, subpats, vdef_opt,
|
||||
ast.ann_type(t, none[vec[@ty.t]]));
|
||||
ast.ann_type(t, tps_opt));
|
||||
}
|
||||
case (ty.ty_fn(_, ?args, ?tag_ty)) {
|
||||
// N-ary tag variant.
|
||||
@ -1115,7 +1116,7 @@ fn demand_pat(&@fn_ctxt fcx, @ty.t expected, @ast.pat pat) -> @ast.pat {
|
||||
i += 1u;
|
||||
}
|
||||
p_1 = ast.pat_tag(id, new_subpats, vdef_opt,
|
||||
ast.ann_type(tag_ty, none[vec[@ty.t]]));
|
||||
ast.ann_type(tag_ty, tps_opt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user