From b2b8002fd325aa5a6f79d0306f508b4c17cd90af Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 15 Jun 2011 21:38:43 +0200 Subject: [PATCH] Fix unsafe uses of aliases in tail calls --- src/comp/middle/trans.rs | 8 +++--- src/comp/middle/typeck.rs | 10 ++++---- src/lib/list.rs | 53 ++++++++++++++++++++++++++------------- 3 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 3b27c8597ed77..9605f4d6e63d1 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -1115,7 +1115,7 @@ fn trans_non_gc_free(&@block_ctxt cx, ValueRef v) -> result { fn find_scope_cx(&@block_ctxt cx) -> @block_ctxt { if (cx.kind != NON_SCOPE_BLOCK) { ret cx; } alt (cx.parent) { - case (parent_some(?b)) { be find_scope_cx(b); } + case (parent_some(?b)) { ret find_scope_cx(b); } case (parent_none) { cx.fcx.lcx.ccx.sess.bug("trans::find_scope_cx() " + "called on parentless block_ctxt"); @@ -2455,7 +2455,7 @@ fn iter_structural_ty(&@block_ctxt cx, ValueRef v, &ty::t t, val_and_ty_fn f) ty::t t) -> result { ret f(cx, av, t); } - be iter_structural_ty_full(cx, v, v, t, bind adaptor_fn(f, _, _, _, _)); + ret iter_structural_ty_full(cx, v, v, t, bind adaptor_fn(f, _, _, _, _)); } fn iter_structural_ty_full(&@block_ctxt cx, ValueRef av, ValueRef bv, @@ -2693,8 +2693,8 @@ fn iter_sequence_inner(&@block_ctxt cx, ValueRef src, ret f(cx, load_if_immediate(cx, p, elt_ty), elt_ty); } auto elt_sz = size_of(cx, elt_ty); - be iter_sequence_raw(elt_sz.bcx, src, src, src_lim, elt_sz.val, - bind adaptor_fn(f, elt_ty, _, _, _)); + ret iter_sequence_raw(elt_sz.bcx, src, src, src_lim, elt_sz.val, + bind adaptor_fn(f, elt_ty, _, _, _)); } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index d86aa74c1bd4f..48ca4d8a8bc84 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -388,7 +388,7 @@ mod write { // Writes a type parameter count and type pair into the node type table. fn ty(&ty::ctxt tcx, uint node_id, &ty_param_substs_opt_and_ty tpot) { assert (!ty::type_contains_vars(tcx, tpot._1)); - be inner(tcx.node_types, node_id, tpot); + ret inner(tcx.node_types, node_id, tpot); } // Writes a type parameter count and type pair into the node type table. @@ -404,23 +404,23 @@ mod write { // Writes a type with no type parameters into the node type table. fn ty_only(&ty::ctxt tcx, uint node_id, ty::t typ) { - be ty(tcx, node_id, tup(none[vec[ty::t]], typ)); + ret ty(tcx, node_id, tup(none[vec[ty::t]], typ)); } // Writes a type with no type parameters into the node type table. This // function allows for the possibility of type variables. fn ty_only_fixup(@fn_ctxt fcx, uint node_id, ty::t typ) { - be ty_fixup(fcx, node_id, tup(none[vec[ty::t]], typ)); + ret ty_fixup(fcx, node_id, tup(none[vec[ty::t]], typ)); } // Writes a nil type into the node type table. fn nil_ty(&ty::ctxt tcx, uint node_id) { - be ty(tcx, node_id, tup(none[vec[ty::t]], ty::mk_nil(tcx))); + ret ty(tcx, node_id, tup(none[vec[ty::t]], ty::mk_nil(tcx))); } // Writes the bottom type into the node type table. fn bot_ty(&ty::ctxt tcx, uint node_id) { - be ty(tcx, node_id, tup(none[vec[ty::t]], ty::mk_bot(tcx))); + ret ty(tcx, node_id, tup(none[vec[ty::t]], ty::mk_bot(tcx))); } } diff --git a/src/lib/list.rs b/src/lib/list.rs index edd14a30133b0..a752e005b5e30 100644 --- a/src/lib/list.rs +++ b/src/lib/list.rs @@ -18,35 +18,52 @@ fn from_vec[T](vec[T] v) -> list[T] { ret l; } -fn foldl[T, U](&list[T] ls, &U u, fn(&T, &U) -> U f) -> U { - alt (ls) { - case (cons(?hd, ?tl)) { - auto u_ = f(hd, u); - be foldl[T, U](*tl, u_, f); +fn foldl[T, U](&list[T] ls_, &U u, fn(&T, &U) -> U f) -> U { + let U accum = u; + auto ls = ls_; + while (true) { + alt (ls) { + case (cons(?hd, ?tl)) { + accum = f(hd, accum); + ls = *tl; + } + case (nil) { break; } } - case (nil) { ret u; } } + ret accum; } -fn find[T, U](&list[T] ls, fn(&T) -> option::t[U] f) -> option::t[U] { - alt (ls) { - case (cons(?hd, ?tl)) { - alt (f(hd)) { - case (none) { be find[T, U](*tl, f); } - case (some(?res)) { ret some[U](res); } +fn find[T, U](&list[T] ls_, fn(&T) -> option::t[U] f) -> option::t[U] { + auto ls = ls_; + while (true) { + alt (ls) { + case (cons(?hd, ?tl)) { + alt (f(hd)) { + case (none) { ls = *tl; } + case (some(?res)) { ret some(res); } + } } + case (nil) { break; } } - case (nil) { ret none[U]; } } + ret none; } -fn has[T](&list[T] ls, &T elt) -> bool { - alt (ls) { - case (cons(?hd, ?tl)) { - if (elt == hd) { ret true; } else { be has(*tl, elt); } +fn has[T](&list[T] ls_, &T elt) -> bool { + auto ls = ls_; + while (true) { + alt (ls) { + case (cons(?hd, ?tl)) { + if (elt == hd) { + ret true; + } else { + ls = *tl; + } + } + case (nil) { ret false; } } - case (nil) { ret false; } } + ret false; // Typestate checker doesn't understand infinite loops } fn length[T](&list[T] ls) -> uint {