Permalink
Browse files

change list so that it must be used in a purely boxed fashion

The old way was inconsistent---the head was unboxed but the
tail was boxed.  This resulted in numerous needless copies and
also made the borrow check unhappy, because the head tended to be
stored in mutable memory.
  • Loading branch information...
1 parent 8e73bb6 commit 34b42eeb657dfe051ebaf0f95ba5a428441b04af @nikomatsakis nikomatsakis committed May 21, 2012
View
@@ -3,9 +3,10 @@
export arena, arena_with_size;
import list;
+import list::{list, cons, nil};
type chunk = {data: [u8], mut fill: uint};
-type arena = {mut chunks: list::list<@chunk>};
+type arena = {mut chunks: @list<@chunk>};
fn chunk(size: uint) -> @chunk {
let mut v = [];
@@ -14,7 +15,7 @@ fn chunk(size: uint) -> @chunk {
}
fn arena_with_size(initial_size: uint) -> arena {
- ret {mut chunks: list::cons(chunk(initial_size), @list::nil)};
+ ret {mut chunks: @cons(chunk(initial_size), @nil)};
}
fn arena() -> arena {
@@ -28,7 +29,7 @@ impl arena for arena {
let chunk_size = vec::capacity(head.data);
let new_min_chunk_size = uint::max(n_bytes, chunk_size);
head = chunk(uint::next_power_of_two(new_min_chunk_size + 1u));
- self.chunks = list::cons(head, @self.chunks);
+ self.chunks = @cons(head, self.chunks);
ret self.alloc(n_bytes, align);
}
View
@@ -11,7 +11,7 @@ enum list<T> {
#[doc = "Create a list from a vector"]
fn from_vec<T: copy>(v: [const T]) -> @list<T> {
- @vec::foldr(v, @nil::<T>, { |h, t| @cons(h, t) })
+ vec::foldr(v, @nil::<T>, { |h, t| @cons(h, t) })
}
#[doc = "
@@ -43,7 +43,7 @@ is returned. If `f` matches no elements then none is returned.
fn find<T: copy>(ls: @list<T>, f: fn(T) -> bool) -> option<T> {
let mut ls = ls;
loop {
- ls = alt ls {
+ ls = alt *ls {
cons(hd, tl) {
if f(hd) { ret some(hd); }
tl
@@ -82,7 +82,7 @@ fn len<T>(ls: @list<T>) -> uint {
}
#[doc = "Returns all but the first element of a list"]
-pure fn tail<T: copy>(ls: @list<T>) -> list<T> {
+pure fn tail<T: copy>(ls: @list<T>) -> @list<T> {
alt *ls {
cons(_, tl) { ret tl; }
nil { fail "list empty" }
@@ -98,7 +98,7 @@ pure fn head<T: copy>(ls: @list<T>) -> T {
pure fn append<T: copy>(l: @list<T>, m: @list<T>) -> @list<T> {
alt *l {
nil { ret m; }
- cons(x, xs) { let rest = append(*xs, m); ret @cons(x, @rest); }
+ cons(x, xs) { let rest = append(xs, m); ret @cons(x, rest); }
}
}
@@ -117,12 +117,13 @@ fn iter<T>(l: @list<T>, f: fn(T)) {
}
#[doc = "Iterate over a list"]
-fn each<T>(l: list<T>, f: fn(T) -> bool) {
+fn each<T>(l: @list<T>, f: fn(T) -> bool) {
let mut cur = l;
loop {
cur = alt *cur {
cons(hd, tl) {
if !f(hd) { ret; }
+ tl
}
nil { break; }
}
@@ -163,7 +164,7 @@ mod tests {
#[test]
fn test_from_vec_empty() {
let empty : @list::list<int> = from_vec([]);
- assert (empty == list::nil::<int>);
+ assert (empty == @list::nil::<int>);
}
#[test]
@@ -208,7 +209,7 @@ mod tests {
fn test_find_fail() {
fn match(&&_i: int) -> bool { ret false; }
let l = from_vec([0, 1, 2]);
- let empty = list::nil::<int>;
+ let empty = @list::nil::<int>;
assert (list::find(l, match) == option::none::<int>);
assert (list::find(empty, match) == option::none::<int>);
}
@@ -33,7 +33,7 @@ type binding = @{node_id: node_id,
// FIXME it may be worthwhile to use a linked list of bindings instead
type scope = {bs: [binding],
- invalid: @mut list<@invalid>};
+ invalid: @mut @list<@invalid>};
fn mk_binding(cx: ctx, id: node_id, span: span, root_var: option<node_id>,
unsafe_tys: [unsafe_ty]) -> binding {
@@ -68,7 +68,7 @@ fn check_crate(tcx: ty::ctxt, crate: @ast::crate) -> (copy_map, ref_map) {
visit_expr: bind visit_expr(cx, _, _, _),
visit_block: bind visit_block(cx, _, _, _)
with *visit::default_visitor::<scope>()};
- let sc = {bs: [], invalid: @mut list::nil};
+ let sc = {bs: [], invalid: @mut @list::nil};
visit::visit_crate(*crate, sc, visit::mk_vt(v));
tcx.sess.abort_if_errors();
ret (cx.copy_map, cx.ref_map);
@@ -88,7 +88,7 @@ fn visit_fn(cx: @ctx, _fk: visit::fn_kind, decl: ast::fn_decl,
check_loop(*cx, sc) {|| v.visit_block(body, sc, v);}
}
ast::proto_box | ast::proto_uniq | ast::proto_bare {
- let sc = {bs: [], invalid: @mut list::nil};
+ let sc = {bs: [], invalid: @mut @list::nil};
v.visit_block(body, sc, v);
}
}
@@ -400,7 +400,7 @@ fn check_var(cx: ctx, ex: @ast::expr, p: @ast::path, id: ast::node_id,
if ty_can_unsafely_include(cx, unsafe_ty, var_t, assign) {
let inv = @{reason: val_taken, node_id: b.node_id,
sp: ex.span, path: p};
- *sc.invalid = list::cons(inv, @*sc.invalid);
+ *sc.invalid = @list::cons(inv, *sc.invalid);
}
}
} else if b.node_id == my_defnum {
@@ -418,7 +418,7 @@ fn check_lval(cx: @ctx, dest: @ast::expr, sc: scope, v: vt<scope>) {
if b.root_var == some(dnum) {
let inv = @{reason: overwritten, node_id: b.node_id,
sp: dest.span, path: p};
- *sc.invalid = list::cons(inv, @*sc.invalid);
+ *sc.invalid = @list::cons(inv, *sc.invalid);
}
}
}
@@ -791,46 +791,43 @@ fn unsafe_set(from: option<unsafe_ty>) -> [unsafe_ty] {
alt from { some(t) { [t] } _ { [] } }
}
-fn find_invalid(id: node_id, lst: list<@invalid>)
- -> option<@invalid> {
+fn find_invalid(id: node_id, lst: @list<@invalid>) -> option<@invalid> {
let mut cur = lst;
loop {
- alt cur {
+ alt *cur {
list::nil { ret none; }
list::cons(head, tail) {
if head.node_id == id { ret some(head); }
- cur = *tail;
+ cur = tail;
}
}
};
}
-fn join_invalid(a: list<@invalid>, b: list<@invalid>) -> list<@invalid> {
+fn join_invalid(a: @list<@invalid>, b: @list<@invalid>) -> @list<@invalid> {
let mut result = a;
list::iter(b) {|elt|
let mut found = false;
list::iter(a) {|e| if e == elt { found = true; } }
- if !found { result = list::cons(elt, @result); }
+ if !found { result = @list::cons(elt, result); }
}
result
}
-fn filter_invalid(src: list<@invalid>, bs: [binding]) -> list<@invalid> {
- let mut out = list::nil, cur = src;
- while cur != list::nil {
- alt cur {
+fn filter_invalid(src: @list<@invalid>, bs: [binding]) -> @list<@invalid> {
+ let mut out = @list::nil, cur = src;
+ loop {
+ alt *cur {
list::cons(head, tail) {
let p = vec::position(bs, {|b| b.node_id == head.node_id});
- if !is_none(p) { out = list::cons(head, @out); }
- cur = *tail;
+ if !is_none(p) { out = @list::cons(head, out); }
+ cur = tail;
}
list::nil {
- // typestate would help...
- unreachable();
+ ret out;
}
}
}
- ret out;
}
fn err(cx: ctx, sp: span, err: str) {
@@ -37,7 +37,7 @@ enum seen { unset, seen(node_id), }
enum block_type { func, lp, }
enum use { var_use(node_id), close_over(node_id), }
-type set = [{def: node_id, uses: list<use>}];
+type set = [{def: node_id, uses: @list<use>}];
type bl = @{type: block_type, mut second: bool, mut exits: [set]};
enum use_id { path(node_id), close(node_id, node_id) }
@@ -52,7 +52,7 @@ type ctx = {last_uses: std::map::hashmap<use_id, bool>,
tcx: ty::ctxt,
// The current set of local last uses
mut current: set,
- mut blocks: list<bl>};
+ mut blocks: @list<bl>};
fn find_last_uses(c: @crate, def_map: resolve::def_map,
ref_map: alias::ref_map, tcx: ty::ctxt)
@@ -67,7 +67,7 @@ fn find_last_uses(c: @crate, def_map: resolve::def_map,
ref_map: ref_map,
tcx: tcx,
mut current: [],
- mut blocks: nil};
+ mut blocks: @nil};
visit::visit_crate(*c, cx, v);
let mini_table = std::map::int_hash();
for cx.last_uses.each {|key, val|
@@ -136,7 +136,7 @@ fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
option::iter(def_is_owned_local(cx, my_def)) {|nid|
clear_in_current(cx, nid, false);
cx.current += [{def: nid,
- uses: cons(var_use(ex.id), @nil)}];
+ uses: @cons(var_use(ex.id), @nil)}];
}
}
}
@@ -249,13 +249,13 @@ fn visit_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
option::iter(def_is_owned_local(cx, v.def)) {|nid|
clear_in_current(cx, nid, false);
cx.current += [{def: nid,
- uses: cons(close_over(id), @nil)}];
+ uses: @cons(close_over(id), @nil)}];
}
}
}
_ {}
}
- let mut old_cur = [], old_blocks = nil;
+ let mut old_cur = [], old_blocks = @nil;
cx.blocks <-> old_blocks;
cx.current <-> old_cur;
visit::visit_fn(fk, decl, body, sp, id, cx, v);
@@ -268,7 +268,7 @@ fn visit_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
fn visit_block(tp: block_type, cx: ctx, visit: fn()) {
let local = @{type: tp, mut second: false, mut exits: []};
- cx.blocks = cons(local, @cx.blocks);
+ cx.blocks = @cons(local, cx.blocks);
visit();
local.second = true;
local.exits = [];
@@ -281,23 +281,20 @@ fn visit_block(tp: block_type, cx: ctx, visit: fn()) {
fn add_block_exit(cx: ctx, tp: block_type) -> bool {
let mut cur = cx.blocks;
- while cur != nil {
- alt cur {
+ loop {
+ alt *cur {
cons(b, tail) {
if (b.type == tp) {
if !b.second { b.exits += [cx.current]; }
ret true;
}
- cur = *tail;
+ cur = tail;
}
nil {
- // typestate can't use the while loop condition --
- // *sigh*
- unreachable();
+ ret false;
}
}
}
- ret false;
}
fn join_branches(branches: [set]) -> set {
@@ -312,7 +309,7 @@ fn join_branches(branches: [set]) -> set {
for vec::each(branches[j]) {|elt2|
if elt2.def == elt.def {
list::iter(elt2.uses) {|e|
- if !list::has(nne, e) { nne = cons(e, @nne); }
+ if !list::has(nne, e) { nne = @cons(e, nne); }
}
}
}
Oops, something went wrong.

0 comments on commit 34b42ee

Please sign in to comment.