diff options
| author | Patrick Walton <[email protected]> | 2011-02-25 12:37:03 -0800 |
|---|---|---|
| committer | Patrick Walton <[email protected]> | 2011-02-25 13:44:08 -0800 |
| commit | 7a1d01effcfa5763bc62aefba40f67ad2130d28d (patch) | |
| tree | 2e26bf45352b71d1e618f359bf388beae354fb21 /src | |
| parent | Pass the abi of native functions all the way to codegen. (diff) | |
| download | rust-7a1d01effcfa5763bc62aefba40f67ad2130d28d.tar.xz rust-7a1d01effcfa5763bc62aefba40f67ad2130d28d.zip | |
rustc: Push type parameters down through alt tag patterns; add a test
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp/middle/typeck.rs | 55 | ||||
| -rw-r--r-- | src/test/run-pass/generic-tag-box-alt.rs | 19 |
2 files changed, 68 insertions, 6 deletions
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index ce1c59ec..a69d169d 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -919,9 +919,42 @@ fn demand_pat(&@fn_ctxt fcx, @ty.t expected, @ast.pat pat) -> @ast.pat { // acquire here with the type parameters provided to us by // "expected". + // Grab the values for the type parameters of the tag from the + // expected type. + let vec[@ty.t] typaram_bindings = vec(); // FIXME: typestate botch + alt (expected.struct) { + case (ty.ty_tag(_, ?tps)) { typaram_bindings = tps; } + case (_) { + log "tag pattern didn't have tag type?!"; + fail; + } + } + + // Get the item corresponding to the tag and its type. auto vdef = option.get[ast.variant_def](vdef_opt); auto variant_ty = fcx.ccx.item_types.get(vdef._1); + // FIXME: typestate botch + let option.t[@ast.item] item_opt = none[@ast.item]; + alt (fcx.ccx.item_items.get(vdef._0)) { + case (any_item_rust(?it)) { item_opt = some[@ast.item](it); } + case (_) { + log "tag item isn't a Rust item?!"; + fail; + } + } + let @ast.item item = option.get[@ast.item](item_opt); + + // Get the IDs of the type parameters from that item. + let vec[ast.ty_param] ty_params = vec(); // FIXME: typestate botch + alt (item.node) { + case (ast.item_tag(_, _, ?tps, _)) { ty_params = tps; } + case (_) { + log "tag's corresponding item isn't a tag?!"; + fail; + } + } + auto subpats_len = _vec.len[@ast.pat](subpats); alt (variant_ty.struct) { case (ty.ty_tag(_, _)) { @@ -930,10 +963,14 @@ fn demand_pat(&@fn_ctxt fcx, @ty.t expected, @ast.pat pat) -> @ast.pat { p_1 = ast.pat_tag(id, subpats, vdef_opt, ast.ann_type(t)); } case (ty.ty_fn(_, ?args, ?tag_ty)) { + // N-ary tag variant. let vec[@ast.pat] new_subpats = vec(); auto i = 0u; for (arg a in args) { - auto new_subpat = demand_pat(fcx, a.ty, subpats.(i)); + auto arg_ty = ty.substitute_ty_params(ty_params, + typaram_bindings, a.ty); + auto new_subpat = demand_pat(fcx, arg_ty, + subpats.(i)); new_subpats += vec(new_subpat); i += 1u; } @@ -1260,14 +1297,13 @@ fn check_pat(&@fn_ctxt fcx, @ast.pat pat) -> @ast.pat { new_subpats += vec(check_pat(fcx, subpat)); } - auto ann = ast.ann_type(tag_ty); + auto tag_ty_g = generalize_ty(fcx.ccx, tag_ty); + auto ann = ast.ann_type(tag_ty_g); new_pat = ast.pat_tag(p, new_subpats, vdef_opt, ann); } // Nullary variants have tag types. - case (ty.ty_tag(?tid, _)) { - // TODO: ty params - + case (ty.ty_tag(?tid, ?tps)) { auto subpats_len = _vec.len[@ast.pat](subpats); if (subpats_len > 0u) { // TODO: pluralize properly @@ -1281,7 +1317,14 @@ fn check_pat(&@fn_ctxt fcx, @ast.pat pat) -> @ast.pat { fail; // TODO: recover } - let vec[@ty.t] tys = vec(); // FIXME + // Add the appropriate number of type variables. + let vec[@ty.t] tys = vec(); + auto i = 0u; + while (i < _vec.len[@ty.t](tps)) { + tys += vec(next_ty_var(fcx.ccx)); + i += 1u; + } + auto ann = ast.ann_type(plain_ty(ty.ty_tag(tid, tys))); new_pat = ast.pat_tag(p, subpats, vdef_opt, ann); } diff --git a/src/test/run-pass/generic-tag-box-alt.rs b/src/test/run-pass/generic-tag-box-alt.rs new file mode 100644 index 00000000..2727885a --- /dev/null +++ b/src/test/run-pass/generic-tag-box-alt.rs @@ -0,0 +1,19 @@ +tag foo[T] { + arm(@T); +} + +fn altfoo[T](foo[T] f) { + auto hit = false; + alt (f) { + case (arm[T](?x)) { + log "in arm"; + hit = true; + } + } + check (hit); +} + +fn main() { + altfoo[int](arm[int](@10)); +} + |