Skip to content

Commit

Permalink
Fix unsafe uses of aliases in tail calls
Browse files Browse the repository at this point in the history
  • Loading branch information
marijnh committed Jun 15, 2011
1 parent 0987b17 commit b2b8002
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 27 deletions.
8 changes: 4 additions & 4 deletions src/comp/middle/trans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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, _, _, _));
}


Expand Down
10 changes: 5 additions & 5 deletions src/comp/middle/typeck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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)));
}
}

Expand Down
53 changes: 35 additions & 18 deletions src/lib/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit b2b8002

Please sign in to comment.