Skip to content

Commit 790084c

Browse files
committed
rustc: Make fold_ty no longer use an object; introduce walk_ty
1 parent 232c450 commit 790084c

File tree

3 files changed

+160
-115
lines changed

3 files changed

+160
-115
lines changed

src/comp/middle/trans.rs

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,24 +1477,21 @@ fn linearize_ty_params(@block_ctxt cx, @ty.t t) ->
14771477
mutable vec[ValueRef] vals,
14781478
mutable vec[uint] defs);
14791479

1480-
state obj folder(@rr r) {
1481-
fn fold_simple_ty(@ty.t t) -> @ty.t {
1482-
alt(t.struct) {
1483-
case (ty.ty_param(?pid)) {
1484-
let bool seen = false;
1485-
for (uint d in r.defs) {
1486-
if (d == pid) {
1487-
seen = true;
1488-
}
1489-
}
1490-
if (!seen) {
1491-
r.vals += vec(r.cx.fcx.lltydescs.get(pid));
1492-
r.defs += vec(pid);
1480+
fn linearizer(@rr r, @ty.t t) {
1481+
alt(t.struct) {
1482+
case (ty.ty_param(?pid)) {
1483+
let bool seen = false;
1484+
for (uint d in r.defs) {
1485+
if (d == pid) {
1486+
seen = true;
14931487
}
14941488
}
1495-
case (_) { }
1489+
if (!seen) {
1490+
r.vals += vec(r.cx.fcx.lltydescs.get(pid));
1491+
r.defs += vec(pid);
1492+
}
14961493
}
1497-
ret t;
1494+
case (_) { }
14981495
}
14991496
}
15001497

@@ -1503,7 +1500,8 @@ fn linearize_ty_params(@block_ctxt cx, @ty.t t) ->
15031500
mutable vals = param_vals,
15041501
mutable defs = param_defs);
15051502

1506-
ty.fold_ty(folder(x), t);
1503+
auto f = bind linearizer(x, _);
1504+
ty.walk_ty(f, t);
15071505

15081506
ret tup(x.defs, x.vals);
15091507
}

src/comp/middle/ty.rs

Lines changed: 136 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -261,52 +261,114 @@ fn ty_to_str(&@t typ) -> str {
261261

262262
// Type folds
263263

264-
type ty_fold = state obj {
265-
fn fold_simple_ty(@t ty) -> @t;
266-
};
264+
type ty_walk = fn(@t);
265+
266+
fn walk_ty(ty_walk walker, @t ty) {
267+
alt (ty.struct) {
268+
case (ty_nil) { /* no-op */ }
269+
case (ty_bool) { /* no-op */ }
270+
case (ty_int) { /* no-op */ }
271+
case (ty_uint) { /* no-op */ }
272+
case (ty_float) { /* no-op */ }
273+
case (ty_machine(_)) { /* no-op */ }
274+
case (ty_char) { /* no-op */ }
275+
case (ty_str) { /* no-op */ }
276+
case (ty_type) { /* no-op */ }
277+
case (ty_native) { /* no-op */ }
278+
case (ty_box(?tm)) { walk_ty(walker, tm.ty); }
279+
case (ty_vec(?tm)) { walk_ty(walker, tm.ty); }
280+
case (ty_port(?subty)) { walk_ty(walker, subty); }
281+
case (ty_chan(?subty)) { walk_ty(walker, subty); }
282+
case (ty_tag(?tid, ?subtys)) {
283+
for (@t subty in subtys) {
284+
walk_ty(walker, subty);
285+
}
286+
}
287+
case (ty_tup(?mts)) {
288+
for (mt tm in mts) {
289+
walk_ty(walker, tm.ty);
290+
}
291+
}
292+
case (ty_rec(?fields)) {
293+
for (field fl in fields) {
294+
walk_ty(walker, fl.mt.ty);
295+
}
296+
}
297+
case (ty_fn(?proto, ?args, ?ret_ty)) {
298+
for (arg a in args) {
299+
walk_ty(walker, a.ty);
300+
}
301+
walk_ty(walker, ret_ty);
302+
}
303+
case (ty_native_fn(?abi, ?args, ?ret_ty)) {
304+
for (arg a in args) {
305+
walk_ty(walker, a.ty);
306+
}
307+
walk_ty(walker, ret_ty);
308+
}
309+
case (ty_obj(?methods)) {
310+
let vec[method] new_methods = vec();
311+
for (method m in methods) {
312+
for (arg a in m.inputs) {
313+
walk_ty(walker, a.ty);
314+
}
315+
walk_ty(walker, m.output);
316+
}
317+
}
318+
case (ty_var(_)) { /* no-op */ }
319+
case (ty_local(_)) { /* no-op */ }
320+
case (ty_param(_)) { /* no-op */ }
321+
case (ty_bound_param(_)) { /* no-op */ }
322+
}
267323

268-
fn fold_ty(ty_fold fld, @t ty) -> @t {
324+
walker(ty);
325+
}
326+
327+
type ty_fold = fn(@t) -> @t;
328+
329+
fn fold_ty(ty_fold fld, @t ty_0) -> @t {
269330
fn rewrap(@t orig, &sty new) -> @t {
270331
ret @rec(struct=new, cname=orig.cname);
271332
}
272333

334+
auto ty = ty_0;
273335
alt (ty.struct) {
274-
case (ty_nil) { ret fld.fold_simple_ty(ty); }
275-
case (ty_bool) { ret fld.fold_simple_ty(ty); }
276-
case (ty_int) { ret fld.fold_simple_ty(ty); }
277-
case (ty_uint) { ret fld.fold_simple_ty(ty); }
278-
case (ty_float) { ret fld.fold_simple_ty(ty); }
279-
case (ty_machine(_)) { ret fld.fold_simple_ty(ty); }
280-
case (ty_char) { ret fld.fold_simple_ty(ty); }
281-
case (ty_str) { ret fld.fold_simple_ty(ty); }
282-
case (ty_type) { ret fld.fold_simple_ty(ty); }
283-
case (ty_native) { ret fld.fold_simple_ty(ty); }
336+
case (ty_nil) { /* no-op */ }
337+
case (ty_bool) { /* no-op */ }
338+
case (ty_int) { /* no-op */ }
339+
case (ty_uint) { /* no-op */ }
340+
case (ty_float) { /* no-op */ }
341+
case (ty_machine(_)) { /* no-op */ }
342+
case (ty_char) { /* no-op */ }
343+
case (ty_str) { /* no-op */ }
344+
case (ty_type) { /* no-op */ }
345+
case (ty_native) { /* no-op */ }
284346
case (ty_box(?tm)) {
285-
ret rewrap(ty, ty_box(rec(ty=fold_ty(fld, tm.ty), mut=tm.mut)));
347+
ty = rewrap(ty, ty_box(rec(ty=fold_ty(fld, tm.ty), mut=tm.mut)));
286348
}
287349
case (ty_vec(?tm)) {
288-
ret rewrap(ty, ty_vec(rec(ty=fold_ty(fld, tm.ty), mut=tm.mut)));
350+
ty = rewrap(ty, ty_vec(rec(ty=fold_ty(fld, tm.ty), mut=tm.mut)));
289351
}
290352
case (ty_port(?subty)) {
291-
ret rewrap(ty, ty_port(fold_ty(fld, subty)));
353+
ty = rewrap(ty, ty_port(fold_ty(fld, subty)));
292354
}
293355
case (ty_chan(?subty)) {
294-
ret rewrap(ty, ty_chan(fold_ty(fld, subty)));
356+
ty = rewrap(ty, ty_chan(fold_ty(fld, subty)));
295357
}
296358
case (ty_tag(?tid, ?subtys)) {
297359
let vec[@t] new_subtys = vec();
298360
for (@t subty in subtys) {
299361
new_subtys += vec(fold_ty(fld, subty));
300362
}
301-
ret rewrap(ty, ty_tag(tid, new_subtys));
363+
ty = rewrap(ty, ty_tag(tid, new_subtys));
302364
}
303365
case (ty_tup(?mts)) {
304366
let vec[mt] new_mts = vec();
305367
for (mt tm in mts) {
306368
auto new_subty = fold_ty(fld, tm.ty);
307369
new_mts += vec(rec(ty=new_subty, mut=tm.mut));
308370
}
309-
ret rewrap(ty, ty_tup(new_mts));
371+
ty = rewrap(ty, ty_tup(new_mts));
310372
}
311373
case (ty_rec(?fields)) {
312374
let vec[field] new_fields = vec();
@@ -315,23 +377,24 @@ fn fold_ty(ty_fold fld, @t ty) -> @t {
315377
auto new_mt = rec(ty=new_ty, mut=fl.mt.mut);
316378
new_fields += vec(rec(ident=fl.ident, mt=new_mt));
317379
}
318-
ret rewrap(ty, ty_rec(new_fields));
380+
ty = rewrap(ty, ty_rec(new_fields));
319381
}
320382
case (ty_fn(?proto, ?args, ?ret_ty)) {
321383
let vec[arg] new_args = vec();
322384
for (arg a in args) {
323385
auto new_ty = fold_ty(fld, a.ty);
324386
new_args += vec(rec(mode=a.mode, ty=new_ty));
325387
}
326-
ret rewrap(ty, ty_fn(proto, new_args, fold_ty(fld, ret_ty)));
388+
ty = rewrap(ty, ty_fn(proto, new_args, fold_ty(fld, ret_ty)));
327389
}
328390
case (ty_native_fn(?abi, ?args, ?ret_ty)) {
329391
let vec[arg] new_args = vec();
330392
for (arg a in args) {
331393
auto new_ty = fold_ty(fld, a.ty);
332394
new_args += vec(rec(mode=a.mode, ty=new_ty));
333395
}
334-
ret rewrap(ty, ty_native_fn(abi, new_args, fold_ty(fld, ret_ty)));
396+
ty = rewrap(ty, ty_native_fn(abi, new_args,
397+
fold_ty(fld, ret_ty)));
335398
}
336399
case (ty_obj(?methods)) {
337400
let vec[method] new_methods = vec();
@@ -344,15 +407,15 @@ fn fold_ty(ty_fold fld, @t ty) -> @t {
344407
inputs=new_args,
345408
output=fold_ty(fld, m.output)));
346409
}
347-
ret rewrap(ty, ty_obj(new_methods));
410+
ty = rewrap(ty, ty_obj(new_methods));
348411
}
349-
case (ty_var(_)) { ret fld.fold_simple_ty(ty); }
350-
case (ty_local(_)) { ret fld.fold_simple_ty(ty); }
351-
case (ty_param(_)) { ret fld.fold_simple_ty(ty); }
352-
case (ty_bound_param(_)) { ret fld.fold_simple_ty(ty); }
412+
case (ty_var(_)) { /* no-op */ }
413+
case (ty_local(_)) { /* no-op */ }
414+
case (ty_param(_)) { /* no-op */ }
415+
case (ty_bound_param(_)) { /* no-op */ }
353416
}
354417

355-
fail;
418+
ret fld(ty);
356419
}
357420

358421
// Type utilities
@@ -655,45 +718,41 @@ fn triv_ann(@ty.t typ) -> ast.ann {
655718

656719
// Returns the number of distinct type parameters in the given type.
657720
fn count_ty_params(@t ty) -> uint {
658-
state obj ty_param_counter(@mutable vec[uint] param_indices) {
659-
fn fold_simple_ty(@t ty) -> @t {
660-
alt (ty.struct) {
661-
case (ty_param(?param_idx)) {
662-
auto seen = false;
663-
for (uint other_param_idx in *param_indices) {
664-
if (param_idx == other_param_idx) {
665-
seen = true;
666-
}
667-
}
668-
if (!seen) {
669-
*param_indices += vec(param_idx);
721+
fn counter(@mutable vec[uint] param_indices, @t ty) {
722+
alt (ty.struct) {
723+
case (ty_param(?param_idx)) {
724+
auto seen = false;
725+
for (uint other_param_idx in *param_indices) {
726+
if (param_idx == other_param_idx) {
727+
seen = true;
670728
}
671729
}
672-
case (_) { /* fall through */ }
730+
if (!seen) {
731+
*param_indices += vec(param_idx);
732+
}
673733
}
674-
ret ty;
734+
case (_) { /* fall through */ }
675735
}
676736
}
677737

678738
let vec[uint] v = vec(); // FIXME: typechecker botch
679739
let @mutable vec[uint] param_indices = @mutable v;
680-
fold_ty(ty_param_counter(param_indices), ty);
740+
auto f = bind counter(param_indices, _);
741+
walk_ty(f, ty);
681742
ret _vec.len[uint](*param_indices);
682743
}
683744

684745
fn type_contains_vars(@t typ) -> bool {
685-
state obj ty_var_counter(@mutable bool flag) {
686-
fn fold_simple_ty(@t typ) -> @t {
687-
alt (typ.struct) {
746+
fn checker(@mutable bool flag, @t typ) {
747+
alt (typ.struct) {
688748
case (ty_var(_)) { *flag = true; }
689749
case (_) { /* fall through */ }
690-
}
691-
ret typ;
692750
}
693751
}
694752

695753
let @mutable bool flag = @mutable false;
696-
fold_ty(ty_var_counter(flag), typ);
754+
auto f = bind checker(flag, _);
755+
walk_ty(f, typ);
697756
ret *flag;
698757
}
699758

@@ -1684,26 +1743,23 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
16841743

16851744
// Performs type binding substitution.
16861745
fn substitute(var_bindings bindings, vec[@t] set_types, @t typ) -> @t {
1687-
state obj folder(tup(var_bindings, vec[@t]) env) {
1688-
fn fold_simple_ty(@t typ) -> @t {
1689-
auto bindings = env._0;
1690-
auto types = env._1;
1691-
alt (typ.struct) {
1746+
fn substituter(var_bindings bindings, vec[@t] types, @t typ) -> @t {
1747+
alt (typ.struct) {
16921748
case (ty_var(?id)) {
16931749
alt (bindings.var_ids.find(id)) {
1694-
case (some[uint](?n)) {
1695-
auto root = UFind.find(bindings.sets, n);
1696-
ret types.(root);
1697-
}
1698-
case (none[uint]) { ret typ; }
1750+
case (some[uint](?n)) {
1751+
auto root = UFind.find(bindings.sets, n);
1752+
ret types.(root);
1753+
}
1754+
case (none[uint]) { ret typ; }
16991755
}
17001756
}
17011757
case (_) { ret typ; }
1702-
}
17031758
}
17041759
}
17051760

1706-
ret ty.fold_ty(folder(tup(bindings, set_types)), typ);
1761+
auto f = bind substituter(bindings, set_types, _);
1762+
ret fold_ty(f, typ);
17071763
}
17081764

17091765
fn unify_sets(&var_bindings bindings) -> vec[@t] {
@@ -1804,41 +1860,35 @@ fn type_err_to_str(&ty.type_err err) -> str {
18041860
// Performs bound type parameter replacement using the supplied mapping from
18051861
// parameter IDs to types.
18061862
fn substitute_type_params(vec[@t] bindings, @t typ) -> @t {
1807-
state obj param_replacer(vec[@t] bindings) {
1808-
fn fold_simple_ty(@t typ) -> @t {
1809-
alt (typ.struct) {
1810-
case (ty_bound_param(?param_index)) {
1811-
ret bindings.(param_index);
1812-
}
1813-
case (_) { ret typ; }
1863+
fn replacer(vec[@t] bindings, @t typ) -> @t {
1864+
alt (typ.struct) {
1865+
case (ty_bound_param(?param_index)) {
1866+
ret bindings.(param_index);
18141867
}
1868+
case (_) { ret typ; }
18151869
}
18161870
}
1817-
auto replacer = param_replacer(bindings);
1818-
ret fold_ty(replacer, typ);
1871+
1872+
auto f = bind replacer(bindings, _);
1873+
ret fold_ty(f, typ);
18191874
}
18201875

18211876
// Converts type parameters in a type to bound type parameters.
18221877
fn bind_params_in_type(@t typ) -> @t {
1823-
state obj folder(() env) {
1824-
fn fold_simple_ty(@t typ) -> @t {
1825-
alt (typ.struct) {
1826-
case (ty_bound_param(?index)) {
1827-
log "bind_params_in_type() called on type that already " +
1828-
"has bound params in it";
1829-
fail;
1830-
}
1831-
case (ty_param(?index)) {
1832-
ret plain_ty(ty_bound_param(index));
1833-
}
1834-
case (_) {
1835-
ret typ;
1836-
}
1878+
fn binder(@t typ) -> @t {
1879+
alt (typ.struct) {
1880+
case (ty_bound_param(?index)) {
1881+
log "bind_params_in_type() called on type that already " +
1882+
"has bound params in it";
1883+
fail;
18371884
}
1885+
case (ty_param(?index)) { ret plain_ty(ty_bound_param(index)); }
1886+
case (_) { ret typ; }
18381887
}
18391888
}
18401889

1841-
ret fold_ty(folder(()), typ);
1890+
auto f = binder;
1891+
ret fold_ty(f, typ);
18421892
}
18431893

18441894

0 commit comments

Comments
 (0)