Turn on kind propagation for typarams. Annotate a bunch of typarams in rustc and libstd.

This commit is contained in:
Graydon Hoare 2011-07-29 12:58:52 -07:00
parent c34d74315f
commit f3c05b9fae
9 changed files with 89 additions and 91 deletions

View file

@ -150,7 +150,7 @@ fn parse_ty_constr_arg(st: @pstate, sd: str_def) ->
} }
} }
fn parse_constr[T](st: @pstate, sd: str_def, pser: arg_parser[T]) -> fn parse_constr[@T](st: @pstate, sd: str_def, pser: arg_parser[T]) ->
@ty::constr_general[T] { @ty::constr_general[T] {
let sp = {lo: 0u, hi: 0u}; // FIXME: use a real span let sp = {lo: 0u, hi: 0u}; // FIXME: use a real span
let args: (@sp_constr_arg[T])[] = ~[]; let args: (@sp_constr_arg[T])[] = ~[];

View file

@ -1129,10 +1129,7 @@ fn type_kind(cx: &ctxt, ty: &t) -> ast::kind {
ty_var(_) { fail; } ty_var(_) { fail; }
ty_param(_,k) { ty_param(_,k) {
// FIXME: when you turn this on, the stdlib will break; be sure result = kind::lower_kind(result, k);
// to have a snapshot done that understands kinds before doing so.
// result = kind::lower_kind(result, k);
} }
ty_constr(t, _) { ty_constr(t, _) {

View file

@ -16,7 +16,7 @@ type t[T] =
fn get(int) -> T ; fn get(int) -> T ;
}; };
fn create[T]() -> t[T] { fn create[@T]() -> t[T] {
type cell[T] = option::t[T]; type cell[T] = option::t[T];
let initial_capacity: uint = 32u; // 2^5 let initial_capacity: uint = 32u; // 2^5
@ -26,7 +26,7 @@ fn create[T]() -> t[T] {
*/ */
fn grow[T](nelts: uint, lo: uint, elts: &(cell[T])[mutable ]) -> fn grow[@T](nelts: uint, lo: uint, elts: &(cell[T])[mutable ]) ->
(cell[T])[mutable ] { (cell[T])[mutable ] {
assert (nelts == ivec::len(elts)); assert (nelts == ivec::len(elts));
let rv = ~[mutable ]; let rv = ~[mutable ];
@ -42,10 +42,10 @@ fn create[T]() -> t[T] {
ret rv; ret rv;
} }
fn get[T](elts: &(cell[T])[mutable ], i: uint) -> T { fn get[@T](elts: &(cell[T])[mutable ], i: uint) -> T {
ret alt elts.(i) { option::some(t) { t } _ { fail } }; ret alt elts.(i) { option::some(t) { t } _ { fail } };
} }
obj deque[T](mutable nelts: uint, obj deque[@T](mutable nelts: uint,
mutable lo: uint, mutable lo: uint,
mutable hi: uint, mutable hi: uint,
mutable elts: (cell[T])[mutable ]) { mutable elts: (cell[T])[mutable ]) {

View file

@ -168,7 +168,7 @@ fn grow_fn[T](v: &mutable T[], n: uint, init_fn: fn(uint) -> T ) {
/// Sets the element at position `index` to `val`. If `index` is past the end /// Sets the element at position `index` to `val`. If `index` is past the end
/// of the vector, expands the vector by replicating `initval` to fill the /// of the vector, expands the vector by replicating `initval` to fill the
/// intervening space. /// intervening space.
fn grow_set[T](v: &mutable T[mutable ], index: uint, initval: &T, val: &T) { fn grow_set[@T](v: &mutable T[mutable ], index: uint, initval: &T, val: &T) {
if index >= len(v) { grow_mut(v, index - len(v) + 1u, initval); } if index >= len(v) { grow_mut(v, index - len(v) + 1u, initval); }
v.(index) = val; v.(index) = val;
} }

View file

@ -8,7 +8,7 @@ import option::none;
// our recursion rules do not permit that. // our recursion rules do not permit that.
tag list[T] { cons(T, @list[T]); nil; } tag list[T] { cons(T, @list[T]); nil; }
fn from_vec[T](v: vec[T]) -> list[T] { fn from_vec[@T](v: vec[T]) -> list[T] {
let l = nil[T]; let l = nil[T];
// FIXME: This would be faster and more space efficient if it looped over // FIXME: This would be faster and more space efficient if it looped over
// a reverse vector iterator. Unfortunately generic iterators seem not to // a reverse vector iterator. Unfortunately generic iterators seem not to
@ -18,7 +18,7 @@ fn from_vec[T](v: vec[T]) -> list[T] {
ret l; ret l;
} }
fn foldl[T, U](ls_: &list[T], u: &U, f: fn(&T, &U) -> U ) -> U { fn foldl[@T, @U](ls_: &list[T], u: &U, f: fn(&T, &U) -> U ) -> U {
let accum: U = u; let accum: U = u;
let ls = ls_; let ls = ls_;
while true { while true {
@ -30,7 +30,7 @@ fn foldl[T, U](ls_: &list[T], u: &U, f: fn(&T, &U) -> U ) -> U {
ret accum; ret accum;
} }
fn find[T, U](ls_: &list[T], f: fn(&T) -> option::t[U] ) -> option::t[U] { fn find[@T, @U](ls_: &list[T], f: fn(&T) -> option::t[U] ) -> option::t[U] {
let ls = ls_; let ls = ls_;
while true { while true {
alt ls { alt ls {
@ -43,7 +43,7 @@ fn find[T, U](ls_: &list[T], f: fn(&T) -> option::t[U] ) -> option::t[U] {
ret none; ret none;
} }
fn has[T](ls_: &list[T], elt: &T) -> bool { fn has[@T](ls_: &list[T], elt: &T) -> bool {
let ls = ls_; let ls = ls_;
while true { while true {
alt ls { alt ls {
@ -60,11 +60,11 @@ fn length[T](ls: &list[T]) -> uint {
ret foldl[T, uint](ls, 0u, bind count[T](_, _)); ret foldl[T, uint](ls, 0u, bind count[T](_, _));
} }
fn cdr[T](ls: &list[T]) -> list[T] { alt ls { cons(_, tl) { ret *tl; } } } fn cdr[@T](ls: &list[T]) -> list[T] { alt ls { cons(_, tl) { ret *tl; } } }
fn car[T](ls: &list[T]) -> T { alt ls { cons(hd, _) { ret hd; } } } fn car[@T](ls: &list[T]) -> T { alt ls { cons(hd, _) { ret hd; } } }
fn append[T](l: &list[T], m: &list[T]) -> list[T] { fn append[@T](l: &list[T], m: &list[T]) -> list[T] {
alt l { alt l {
nil. { ret m; } nil. { ret m; }
cons(x, xs) { cons(x, xs) {

View file

@ -19,9 +19,9 @@ type hashmap[K, V] =
}; };
type hashset[K] = hashmap[K, ()]; type hashset[K] = hashmap[K, ()];
fn set_add[K](set: hashset[K], key: &K) -> bool { ret set.insert(key, ()); } fn set_add[@K](set: hashset[K], key: &K) -> bool { ret set.insert(key, ()); }
fn mk_hashmap[K, V](hasher: &hashfn[K], eqer: &eqfn[K]) -> hashmap[K, V] { fn mk_hashmap[@K, @V](hasher: &hashfn[K], eqer: &eqfn[K]) -> hashmap[K, V] {
let initial_capacity: uint = 32u; // 2^5 let initial_capacity: uint = 32u; // 2^5
let load_factor: util::rational = {num: 3, den: 4}; let load_factor: util::rational = {num: 3, den: 4};
@ -53,10 +53,10 @@ fn mk_hashmap[K, V](hasher: &hashfn[K], eqer: &eqfn[K]) -> hashmap[K, V] {
* will fail. * will fail.
*/ */
fn insert_common[K, fn insert_common[@K,
V](hasher: &hashfn[K], eqer: &eqfn[K], @V](hasher: &hashfn[K], eqer: &eqfn[K],
bkts: &(bucket[K, V])[mutable ], nbkts: uint, key: &K, bkts: &(bucket[K, V])[mutable ], nbkts: uint,
val: &V) -> bool { key: &K, val: &V) -> bool {
let i: uint = 0u; let i: uint = 0u;
let h: uint = hasher(key); let h: uint = hasher(key);
while i < nbkts { while i < nbkts {
@ -78,8 +78,8 @@ fn mk_hashmap[K, V](hasher: &hashfn[K], eqer: &eqfn[K]) -> hashmap[K, V] {
fail; // full table fail; // full table
} }
fn find_common[K, fn find_common[@K,
V](hasher: &hashfn[K], eqer: &eqfn[K], @V](hasher: &hashfn[K], eqer: &eqfn[K],
bkts: &(bucket[K, V])[mutable ], nbkts: uint, key: &K) bkts: &(bucket[K, V])[mutable ], nbkts: uint, key: &K)
-> option::t[V] { -> option::t[V] {
let i: uint = 0u; let i: uint = 0u;
@ -101,8 +101,8 @@ fn mk_hashmap[K, V](hasher: &hashfn[K], eqer: &eqfn[K]) -> hashmap[K, V] {
} }
ret option::none[V]; ret option::none[V];
} }
fn rehash[K, fn rehash[@K,
V](hasher: &hashfn[K], eqer: &eqfn[K], @V](hasher: &hashfn[K], eqer: &eqfn[K],
oldbkts: &(bucket[K, V])[mutable ], noldbkts: uint, oldbkts: &(bucket[K, V])[mutable ], noldbkts: uint,
newbkts: &(bucket[K, V])[mutable ], nnewbkts: uint) { newbkts: &(bucket[K, V])[mutable ], nnewbkts: uint) {
for b: bucket[K, V] in oldbkts { for b: bucket[K, V] in oldbkts {
@ -116,8 +116,8 @@ fn mk_hashmap[K, V](hasher: &hashfn[K], eqer: &eqfn[K]) -> hashmap[K, V] {
} }
} }
} }
obj hashmap[K, obj hashmap[@K,
V](hasher: hashfn[K], @V](hasher: hashfn[K],
eqer: eqfn[K], eqer: eqfn[K],
mutable bkts: (bucket[K, V])[mutable ], mutable bkts: (bucket[K, V])[mutable ],
mutable nbkts: uint, mutable nbkts: uint,
@ -199,17 +199,17 @@ fn mk_hashmap[K, V](hasher: &hashfn[K], eqer: &eqfn[K]) -> hashmap[K, V] {
// Hash map constructors for basic types // Hash map constructors for basic types
fn new_str_hash[V]() -> hashmap[str, V] { fn new_str_hash[@V]() -> hashmap[str, V] {
ret mk_hashmap(str::hash, str::eq); ret mk_hashmap(str::hash, str::eq);
} }
fn new_int_hash[V]() -> hashmap[int, V] { fn new_int_hash[@V]() -> hashmap[int, V] {
fn hash_int(x: &int) -> uint { ret x as uint; } fn hash_int(x: &int) -> uint { ret x as uint; }
fn eq_int(a: &int, b: &int) -> bool { ret a == b; } fn eq_int(a: &int, b: &int) -> bool { ret a == b; }
ret mk_hashmap[int, V](hash_int, eq_int); ret mk_hashmap[int, V](hash_int, eq_int);
} }
fn new_uint_hash[V]() -> hashmap[uint, V] { fn new_uint_hash[@V]() -> hashmap[uint, V] {
fn hash_uint(x: &uint) -> uint { ret x; } fn hash_uint(x: &uint) -> uint { ret x; }
fn eq_uint(a: &uint, b: &uint) -> bool { ret a == b; } fn eq_uint(a: &uint, b: &uint) -> bool { ret a == b; }
ret mk_hashmap[uint, V](hash_uint, eq_uint); ret mk_hashmap[uint, V](hash_uint, eq_uint);

View file

@ -11,7 +11,7 @@ export quick_sort3;
type lteq[T] = fn(&T, &T) -> bool ; type lteq[T] = fn(&T, &T) -> bool ;
fn merge_sort[T](le: lteq[T], v: vec[T]) -> vec[T] { fn merge_sort[@T](le: lteq[T], v: vec[T]) -> vec[T] {
fn merge[T](le: lteq[T], a: vec[T], b: vec[T]) -> vec[T] { fn merge[T](le: lteq[T], a: vec[T], b: vec[T]) -> vec[T] {
let rs: vec[T] = []; let rs: vec[T] = [];
let a_len: uint = len[T](a); let a_len: uint = len[T](a);
@ -36,13 +36,13 @@ fn merge_sort[T](le: lteq[T], v: vec[T]) -> vec[T] {
ret merge[T](le, merge_sort[T](le, a), merge_sort[T](le, b)); ret merge[T](le, merge_sort[T](le, a), merge_sort[T](le, b));
} }
fn swap[T](arr: vec[mutable T], x: uint, y: uint) { fn swap[@T](arr: vec[mutable T], x: uint, y: uint) {
let a = arr.(x); let a = arr.(x);
arr.(x) = arr.(y); arr.(x) = arr.(y);
arr.(y) = a; arr.(y) = a;
} }
fn part[T](compare_func: lteq[T], arr: vec[mutable T], left: uint, fn part[@T](compare_func: lteq[T], arr: vec[mutable T], left: uint,
right: uint, pivot: uint) -> uint { right: uint, pivot: uint) -> uint {
let pivot_value = arr.(pivot); let pivot_value = arr.(pivot);
swap[T](arr, pivot, right); swap[T](arr, pivot, right);
@ -59,7 +59,7 @@ fn part[T](compare_func: lteq[T], arr: vec[mutable T], left: uint,
ret storage_index; ret storage_index;
} }
fn qsort[T](compare_func: lteq[T], arr: vec[mutable T], left: uint, fn qsort[@T](compare_func: lteq[T], arr: vec[mutable T], left: uint,
right: uint) { right: uint) {
if right > left { if right > left {
let pivot = (left + right) / 2u; let pivot = (left + right) / 2u;
@ -72,7 +72,7 @@ fn qsort[T](compare_func: lteq[T], arr: vec[mutable T], left: uint,
} }
} }
fn quick_sort[T](compare_func: lteq[T], arr: vec[mutable T]) { fn quick_sort[@T](compare_func: lteq[T], arr: vec[mutable T]) {
if len[T](arr) == 0u { ret; } if len[T](arr) == 0u { ret; }
qsort[T](compare_func, arr, 0u, len[T](arr) - 1u); qsort[T](compare_func, arr, 0u, len[T](arr) - 1u);
} }
@ -82,7 +82,7 @@ fn quick_sort[T](compare_func: lteq[T], arr: vec[mutable T]) {
// http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf // http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf
// According to these slides this is the algorithm of choice for // According to these slides this is the algorithm of choice for
// 'randomly ordered keys, abstract compare' & 'small number of key values' // 'randomly ordered keys, abstract compare' & 'small number of key values'
fn qsort3[T](compare_func_lt: lteq[T], compare_func_eq: lteq[T], fn qsort3[@T](compare_func_lt: lteq[T], compare_func_eq: lteq[T],
arr: vec[mutable T], left: int, right: int) { arr: vec[mutable T], left: int, right: int) {
if right <= left { ret; } if right <= left { ret; }
let v: T = arr.(right); let v: T = arr.(right);
@ -130,7 +130,7 @@ fn qsort3[T](compare_func_lt: lteq[T], compare_func_eq: lteq[T],
qsort3[T](compare_func_lt, compare_func_eq, arr, i, right); qsort3[T](compare_func_lt, compare_func_eq, arr, i, right);
} }
fn quick_sort3[T](compare_func_lt: lteq[T], compare_func_eq: lteq[T], fn quick_sort3[@T](compare_func_lt: lteq[T], compare_func_eq: lteq[T],
arr: vec[mutable T]) { arr: vec[mutable T]) {
if vec::len[T](arr) == 0u { ret; } if vec::len[T](arr) == 0u { ret; }
qsort3[T](compare_func_lt, compare_func_eq, arr, 0, qsort3[T](compare_func_lt, compare_func_eq, arr, 0,
@ -144,8 +144,8 @@ mod ivector {
type lteq[T] = fn(&T, &T) -> bool ; type lteq[T] = fn(&T, &T) -> bool ;
fn merge_sort[T](le: lteq[T], v: &T[]) -> T[] { fn merge_sort[@T](le: lteq[T], v: &T[]) -> T[] {
fn merge[T](le: lteq[T], a: &T[], b: &T[]) -> T[] { fn merge[@T](le: lteq[T], a: &T[], b: &T[]) -> T[] {
let rs: T[] = ~[]; let rs: T[] = ~[];
let a_len: uint = ilen[T](a); let a_len: uint = ilen[T](a);
let a_ix: uint = 0u; let a_ix: uint = 0u;
@ -169,13 +169,13 @@ mod ivector {
ret merge[T](le, merge_sort[T](le, a), merge_sort[T](le, b)); ret merge[T](le, merge_sort[T](le, a), merge_sort[T](le, b));
} }
fn swap[T](arr: &T[mutable ], x: uint, y: uint) { fn swap[@T](arr: &T[mutable ], x: uint, y: uint) {
let a = arr.(x); let a = arr.(x);
arr.(x) = arr.(y); arr.(x) = arr.(y);
arr.(y) = a; arr.(y) = a;
} }
fn part[T](compare_func: lteq[T], arr: &T[mutable ], left: uint, fn part[@T](compare_func: lteq[T], arr: &T[mutable ], left: uint,
right: uint, pivot: uint) -> uint { right: uint, pivot: uint) -> uint {
let pivot_value = arr.(pivot); let pivot_value = arr.(pivot);
swap[T](arr, pivot, right); swap[T](arr, pivot, right);
@ -192,7 +192,7 @@ mod ivector {
ret storage_index; ret storage_index;
} }
fn qsort[T](compare_func: lteq[T], arr: &T[mutable ], left: uint, fn qsort[@T](compare_func: lteq[T], arr: &T[mutable ], left: uint,
right: uint) { right: uint) {
if right > left { if right > left {
let pivot = (left + right) / 2u; let pivot = (left + right) / 2u;
@ -205,7 +205,7 @@ mod ivector {
} }
} }
fn quick_sort[T](compare_func: lteq[T], arr: &T[mutable ]) { fn quick_sort[@T](compare_func: lteq[T], arr: &T[mutable ]) {
if ilen[T](arr) == 0u { ret; } if ilen[T](arr) == 0u { ret; }
qsort[T](compare_func, arr, 0u, ilen[T](arr) - 1u); qsort[T](compare_func, arr, 0u, ilen[T](arr) - 1u);
} }
@ -216,7 +216,7 @@ mod ivector {
// According to these slides this is the algorithm of choice for // According to these slides this is the algorithm of choice for
// 'randomly ordered keys, abstract compare' & 'small number of key // 'randomly ordered keys, abstract compare' & 'small number of key
// values' // values'
fn qsort3[T](compare_func_lt: lteq[T], compare_func_eq: lteq[T], fn qsort3[@T](compare_func_lt: lteq[T], compare_func_eq: lteq[T],
arr: &T[mutable ], left: int, right: int) { arr: &T[mutable ], left: int, right: int) {
if right <= left { ret; } if right <= left { ret; }
let v: T = arr.(right); let v: T = arr.(right);
@ -264,7 +264,7 @@ mod ivector {
qsort3[T](compare_func_lt, compare_func_eq, arr, i, right); qsort3[T](compare_func_lt, compare_func_eq, arr, i, right);
} }
fn quick_sort3[T](compare_func_lt: lteq[T], compare_func_eq: lteq[T], fn quick_sort3[@T](compare_func_lt: lteq[T], compare_func_eq: lteq[T],
arr: &T[mutable ]) { arr: &T[mutable ]) {
if ilen[T](arr) == 0u { ret; } if ilen[T](arr) == 0u { ret; }
qsort3[T](compare_func_lt, compare_func_eq, arr, 0, qsort3[T](compare_func_lt, compare_func_eq, arr, 0,

View file

@ -60,14 +60,14 @@ fn empty_mut[T]() -> vec[mutable T] { ret alloc_mut[T](0u); }
type init_op[T] = fn(uint) -> T ; type init_op[T] = fn(uint) -> T ;
fn init_fn[T](op: &init_op[T], n_elts: uint) -> vec[T] { fn init_fn[@T](op: &init_op[T], n_elts: uint) -> vec[T] {
let v: vec[T] = alloc[T](n_elts); let v: vec[T] = alloc[T](n_elts);
let i: uint = 0u; let i: uint = 0u;
while i < n_elts { v += [op(i)]; i += 1u; } while i < n_elts { v += [op(i)]; i += 1u; }
ret v; ret v;
} }
fn init_fn_mut[T](op: &init_op[T], n_elts: uint) -> vec[mutable T] { fn init_fn_mut[@T](op: &init_op[T], n_elts: uint) -> vec[mutable T] {
let v: vec[mutable T] = alloc_mut[T](n_elts); let v: vec[mutable T] = alloc_mut[T](n_elts);
let i: uint = 0u; let i: uint = 0u;
while i < n_elts { v += [mutable op(i)]; i += 1u; } while i < n_elts { v += [mutable op(i)]; i += 1u; }
@ -76,7 +76,7 @@ fn init_fn_mut[T](op: &init_op[T], n_elts: uint) -> vec[mutable T] {
// init_elt: creates and returns a vector of length n_elts, filled with // init_elt: creates and returns a vector of length n_elts, filled with
// that many copies of element t. // that many copies of element t.
fn init_elt[T](t: &T, n_elts: uint) -> vec[T] { fn init_elt[@T](t: &T, n_elts: uint) -> vec[T] {
/** /**
* FIXME (issue #81): should be: * FIXME (issue #81): should be:
* *
@ -91,7 +91,7 @@ fn init_elt[T](t: &T, n_elts: uint) -> vec[T] {
ret v; ret v;
} }
fn init_elt_mut[T](t: &T, n_elts: uint) -> vec[mutable T] { fn init_elt_mut[@T](t: &T, n_elts: uint) -> vec[mutable T] {
let v: vec[mutable T] = alloc_mut[T](n_elts); let v: vec[mutable T] = alloc_mut[T](n_elts);
let i: uint = n_elts; let i: uint = n_elts;
while i > 0u { i -= 1u; v += [mutable t]; } while i > 0u { i -= 1u; v += [mutable t]; }
@ -113,7 +113,7 @@ fn print_debug_info[T](v: array[T]) { rustrt::vec_print_debug_info[T](v); }
// FIXME: typestate precondition (list is non-empty) // FIXME: typestate precondition (list is non-empty)
// Returns the last element of v. // Returns the last element of v.
fn last[T](v: array[T]) -> option::t[T] { fn last[@T](v: array[T]) -> option::t[T] {
let l = len[T](v); let l = len[T](v);
if l == 0u { ret none[T]; } if l == 0u { ret none[T]; }
ret some[T](v.(l - 1u)); ret some[T](v.(l - 1u));
@ -121,7 +121,7 @@ fn last[T](v: array[T]) -> option::t[T] {
// Returns elements from [start..end) from v. // Returns elements from [start..end) from v.
fn slice[T](v: array[T], start: uint, end: uint) -> vec[T] { fn slice[@T](v: array[T], start: uint, end: uint) -> vec[T] {
assert (start <= end); assert (start <= end);
assert (end <= len[T](v)); assert (end <= len[T](v));
let result = alloc[T](end - start); let result = alloc[T](end - start);
@ -132,7 +132,7 @@ fn slice[T](v: array[T], start: uint, end: uint) -> vec[T] {
// FIXME: Should go away eventually. // FIXME: Should go away eventually.
fn slice_mut[T](v: array[T], start: uint, end: uint) -> vec[mutable T] { fn slice_mut[@T](v: array[T], start: uint, end: uint) -> vec[mutable T] {
assert (start <= end); assert (start <= end);
assert (end <= len[T](v)); assert (end <= len[T](v));
let result = alloc_mut[T](end - start); let result = alloc_mut[T](end - start);
@ -141,7 +141,7 @@ fn slice_mut[T](v: array[T], start: uint, end: uint) -> vec[mutable T] {
ret result; ret result;
} }
fn shift[T](v: &mutable array[T]) -> T { fn shift[@T](v: &mutable array[T]) -> T {
let ln = len[T](v); let ln = len[T](v);
assert (ln > 0u); assert (ln > 0u);
let e = v.(0); let e = v.(0);
@ -149,7 +149,7 @@ fn shift[T](v: &mutable array[T]) -> T {
ret e; ret e;
} }
fn pop[T](v: &mutable array[T]) -> T { fn pop[@T](v: &mutable array[T]) -> T {
let ln = len[T](v); let ln = len[T](v);
assert (ln > 0u); assert (ln > 0u);
ln -= 1u; ln -= 1u;
@ -158,58 +158,59 @@ fn pop[T](v: &mutable array[T]) -> T {
ret e; ret e;
} }
fn top[T](v: &array[T]) -> T { fn top[@T](v: &array[T]) -> T {
let ln = len[T](v); let ln = len[T](v);
assert (ln > 0u); assert (ln > 0u);
ret v.(ln - 1u); ret v.(ln - 1u);
} }
fn push[T](v: &mutable array[T], t: &T) { v += [t]; } fn push[@T](v: &mutable array[T], t: &T) { v += [t]; }
fn unshift[T](v: &mutable array[T], t: &T) { fn unshift[@T](v: &mutable array[T], t: &T) {
let rs = alloc[T](len[T](v) + 1u); let rs = alloc[T](len[T](v) + 1u);
rs += [t]; rs += [t];
rs += v; rs += v;
v = rs; v = rs;
} }
fn grow[T](v: &mutable array[T], n: uint, initval: &T) { fn grow[@T](v: &mutable array[T], n: uint, initval: &T) {
let i: uint = n; let i: uint = n;
while i > 0u { i -= 1u; v += [initval]; } while i > 0u { i -= 1u; v += [initval]; }
} }
fn grow_set[T](v: &mutable vec[mutable T], index: uint, initval: &T, fn grow_set[@T](v: &mutable vec[mutable T], index: uint, initval: &T,
val: &T) { val: &T) {
let length = vec::len(v); let length = vec::len(v);
if index >= length { grow(v, index - length + 1u, initval); } if index >= length { grow(v, index - length + 1u, initval); }
v.(index) = val; v.(index) = val;
} }
fn grow_init_fn[T](v: &mutable array[T], n: uint, init_fn: fn() -> T ) { fn grow_init_fn[@T](v: &mutable array[T], n: uint, init_fn: fn() -> T ) {
let i: uint = n; let i: uint = n;
while i > 0u { i -= 1u; v += [init_fn()]; } while i > 0u { i -= 1u; v += [init_fn()]; }
} }
fn grow_init_fn_set[T](v: &mutable array[T], index: uint, init_fn: fn() -> T, fn grow_init_fn_set[@T](v: &mutable array[T], index: uint, init_fn: fn() -> T,
val: &T) { val: &T) {
let length = vec::len(v); let length = vec::len(v);
if index >= length { grow_init_fn(v, index - length + 1u, init_fn); } if index >= length { grow_init_fn(v, index - length + 1u, init_fn); }
v.(index) = val; v.(index) = val;
} }
fn map[T, U](f: &fn(&T) -> U , v: &vec[T]) -> vec[U] { fn map[@T, @U](f: &fn(&T) -> U , v: &vec[T]) -> vec[U] {
let rs: vec[U] = alloc[U](len[T](v)); let rs: vec[U] = alloc[U](len[T](v));
for ve: T in v { rs += [f(ve)]; } for ve: T in v { rs += [f(ve)]; }
ret rs; ret rs;
} }
fn filter_map[T, U](f: &fn(&T) -> option::t[U] , v: &vec[T]) -> vec[U] { fn filter_map[@T, @U](f: &fn(&T) -> option::t[U] , v: &vec[T]) -> vec[U] {
let rs: vec[U] = []; let rs: vec[U] = [];
for ve: T in v { alt f(ve) { some(elt) { rs += [elt]; } none. { } } } for ve: T in v { alt f(ve) { some(elt) { rs += [elt]; } none. { } } }
ret rs; ret rs;
} }
fn map2[T, U, V](f: &operator2[T, U, V], v0: &vec[T], v1: &vec[U]) -> vec[V] { fn map2[@T, @U, @V](f: &operator2[T, U, V], v0: &vec[T], v1: &vec[U])
-> vec[V] {
let v0_len = len[T](v0); let v0_len = len[T](v0);
if v0_len != len[U](v1) { fail; } if v0_len != len[U](v1) { fail; }
let u: vec[V] = alloc[V](v0_len); let u: vec[V] = alloc[V](v0_len);
@ -218,12 +219,12 @@ fn map2[T, U, V](f: &operator2[T, U, V], v0: &vec[T], v1: &vec[U]) -> vec[V] {
ret u; ret u;
} }
fn find[T](f: fn(&T) -> bool , v: &vec[T]) -> option::t[T] { fn find[@T](f: fn(&T) -> bool , v: &vec[T]) -> option::t[T] {
for elt: T in v { if f(elt) { ret some[T](elt); } } for elt: T in v { if f(elt) { ret some[T](elt); } }
ret none[T]; ret none[T];
} }
fn position[T](x: &T, v: &array[T]) -> option::t[uint] { fn position[@T](x: &T, v: &array[T]) -> option::t[uint] {
let i: uint = 0u; let i: uint = 0u;
while i < len(v) { if x == v.(i) { ret some[uint](i); } i += 1u; } while i < len(v) { if x == v.(i) { ret some[uint](i); } i += 1u; }
ret none[uint]; ret none[uint];
@ -246,7 +247,7 @@ fn count[T](x: &T, v: &array[T]) -> uint {
ret cnt; ret cnt;
} }
fn foldl[T, U](p: fn(&U, &T) -> U , z: &U, v: &vec[T]) -> U { fn foldl[@T, @U](p: fn(&U, &T) -> U , z: &U, v: &vec[T]) -> U {
let sz = len[T](v); let sz = len[T](v);
if sz == 0u { if sz == 0u {
ret z; ret z;
@ -256,7 +257,7 @@ fn foldl[T, U](p: fn(&U, &T) -> U , z: &U, v: &vec[T]) -> U {
} }
} }
fn unzip[T, U](v: &vec[{_0: T, _1: U}]) -> {_0: vec[T], _1: vec[U]} { fn unzip[@T, @U](v: &vec[{_0: T, _1: U}]) -> {_0: vec[T], _1: vec[U]} {
let sz = len(v); let sz = len(v);
if sz == 0u { if sz == 0u {
ret {_0: alloc[T](0u), _1: alloc[U](0u)}; ret {_0: alloc[T](0u), _1: alloc[U](0u)};
@ -271,7 +272,7 @@ fn unzip[T, U](v: &vec[{_0: T, _1: U}]) -> {_0: vec[T], _1: vec[U]} {
// FIXME make the lengths being equal a constraint // FIXME make the lengths being equal a constraint
fn zip[T, U](v: &vec[T], u: &vec[U]) -> vec[{_0: T, _1: U}] { fn zip[@T, @U](v: &vec[T], u: &vec[U]) -> vec[{_0: T, _1: U}] {
let sz = len(v); let sz = len(v);
assert (sz == len(u)); assert (sz == len(u));
if sz == 0u { if sz == 0u {
@ -297,13 +298,13 @@ fn all[T](f: &fn(&T) -> bool , v: &vec[T]) -> bool {
ret true; ret true;
} }
fn clone[T](v: &vec[T]) -> vec[T] { ret slice[T](v, 0u, len[T](v)); } fn clone[@T](v: &vec[T]) -> vec[T] { ret slice[T](v, 0u, len[T](v)); }
fn plus_option[T](v: &mutable vec[T], o: &option::t[T]) { fn plus_option[@T](v: &mutable vec[T], o: &option::t[T]) {
alt o { none. { } some(x) { v += [x]; } } alt o { none. { } some(x) { v += [x]; } }
} }
fn cat_options[T](v: &vec[option::t[T]]) -> vec[T] { fn cat_options[@T](v: &vec[option::t[T]]) -> vec[T] {
let rs: vec[T] = []; let rs: vec[T] = [];
for o: option::t[T] in v { alt o { none. { } some(t) { rs += [t]; } } } for o: option::t[T] in v { alt o { none. { } some(t) { rs += [t]; } } }
ret rs; ret rs;
@ -311,7 +312,7 @@ fn cat_options[T](v: &vec[option::t[T]]) -> vec[T] {
// TODO: Remove in favor of built-in "freeze" operation when it's implemented. // TODO: Remove in favor of built-in "freeze" operation when it's implemented.
fn freeze[T](v: vec[mutable T]) -> vec[T] { fn freeze[@T](v: vec[mutable T]) -> vec[T] {
let result: vec[T] = []; let result: vec[T] = [];
for elem: T in v { result += [elem]; } for elem: T in v { result += [elem]; }
ret result; ret result;
@ -319,7 +320,7 @@ fn freeze[T](v: vec[mutable T]) -> vec[T] {
// Swaps two elements in a vector // Swaps two elements in a vector
fn swap[T](v: &vec[mutable T], a: uint, b: uint) { fn swap[@T](v: &vec[mutable T], a: uint, b: uint) {
let t: T = v.(a); let t: T = v.(a);
v.(a) = v.(b); v.(a) = v.(b);
v.(b) = t; v.(b) = t;
@ -327,7 +328,7 @@ fn swap[T](v: &vec[mutable T], a: uint, b: uint) {
// In place vector reversal // In place vector reversal
fn reverse[T](v: &vec[mutable T]) { fn reverse[@T](v: &vec[mutable T]) {
let i: uint = 0u; let i: uint = 0u;
let ln = len[T](v); let ln = len[T](v);
while i < ln / 2u { swap(v, i, ln - i - 1u); i += 1u; } while i < ln / 2u { swap(v, i, ln - i - 1u); i += 1u; }
@ -335,7 +336,7 @@ fn reverse[T](v: &vec[mutable T]) {
// Functional vector reversal. Returns a reversed copy of v. // Functional vector reversal. Returns a reversed copy of v.
fn reversed[T](v: vec[T]) -> vec[T] { fn reversed[@T](v: vec[T]) -> vec[T] {
let rs: vec[T] = []; let rs: vec[T] = [];
let i = len[T](v); let i = len[T](v);
if i == 0u { ret rs; } else { i -= 1u; } if i == 0u { ret rs; } else { i -= 1u; }
@ -347,7 +348,7 @@ fn reversed[T](v: vec[T]) -> vec[T] {
/// Truncates the vector to length `new_len`. /// Truncates the vector to length `new_len`.
/// FIXME: This relies on a typechecker bug (covariance vs. invariance). /// FIXME: This relies on a typechecker bug (covariance vs. invariance).
fn truncate[T](v: &mutable vec[mutable? T], new_len: uint) { fn truncate[@T](v: &mutable vec[mutable? T], new_len: uint) {
v = slice[T](v, 0u, new_len); v = slice[T](v, 0u, new_len);
} }
// Local Variables: // Local Variables:

View file

@ -1,4 +1,4 @@
fn swap[T](v: &vec[mutable T], i: int, j: int) { v.(i) <-> v.(j); } fn swap[@T](v: &vec[mutable T], i: int, j: int) { v.(i) <-> v.(j); }
fn main() { fn main() {
let a: vec[mutable int] = [mutable 0, 1, 2, 3, 4, 5, 6]; let a: vec[mutable int] = [mutable 0, 1, 2, 3, 4, 5, 6];