Merge branch 'master' into kmath

Conflicts:
	src/libcore/float.rs
This commit is contained in:
Stefan Plantikow 2012-01-05 17:18:40 +01:00
commit c8467977c4
93 changed files with 401 additions and 445 deletions

View File

@ -114,7 +114,7 @@ fn time<T>(do_it: bool, what: str, thunk: fn@() -> T) -> T {
fn inject_libcore_reference(sess: session::session,
crate: @ast::crate) -> @ast::crate {
fn spanned<copy T>(x: T) -> @ast::spanned<T> {
fn spanned<T: copy>(x: T) -> @ast::spanned<T> {
ret @{node: x,
span: {lo: 0u, hi: 0u,
expanded_from: codemap::os_none}};

View File

@ -221,7 +221,7 @@ fn native_abi(attrs: [ast::attribute]) -> either::t<str, ast::native_abi> {
};
}
fn span<copy T>(item: T) -> ast::spanned<T> {
fn span<T: copy>(item: T) -> ast::spanned<T> {
ret {node: item, span: ast_util::dummy_sp()};
}

View File

@ -182,7 +182,7 @@ fn mk_test_module(cx: test_ctxt) -> @ast::item {
ret @item;
}
fn nospan<copy T>(t: T) -> ast::spanned<T> {
fn nospan<T: copy>(t: T) -> ast::spanned<T> {
ret {node: t, span: dummy_sp()};
}

View File

@ -260,7 +260,8 @@ fn resolve_crate(e: env, ident: ast::ident, metas: [@ast::meta_item],
// Now resolve the crates referenced by this crate
let cnum_map = resolve_crate_deps(e, cdata);
let cmeta = {name: ident, data: cdata, cnum_map: cnum_map};
let cmeta = @{name: ident, data: cdata,
cnum_map: cnum_map, cnum: cnum};
let cstore = e.sess.get_cstore();
cstore::set_crate_data(cstore, cnum, cmeta);

View File

@ -58,32 +58,27 @@ fn resolve_path(cstore: cstore::cstore, cnum: ast::crate_num,
fn get_tag_variants(tcx: ty::ctxt, def: ast::def_id) -> [ty::variant_info] {
let cstore = tcx.sess.get_cstore();
let cnum = def.crate;
let cdata = cstore::get_crate_data(cstore, cnum).data;
let resolver = bind translate_def_id(cstore, cnum, _);
ret decoder::get_tag_variants(cdata, def, tcx, resolver)
let cdata = cstore::get_crate_data(cstore, def.crate);
ret decoder::get_tag_variants(cdata, def.node, tcx)
}
fn get_impls_for_mod(cstore: cstore::cstore, def: ast::def_id,
name: option::t<ast::ident>)
-> @[@middle::resolve::_impl] {
let cdata = cstore::get_crate_data(cstore, def.crate).data;
let resolver = bind translate_def_id(cstore, def.crate, _);
decoder::get_impls_for_mod(cdata, def, name, resolver)
let cdata = cstore::get_crate_data(cstore, def.crate);
decoder::get_impls_for_mod(cdata, def.node, name)
}
fn get_iface_methods(tcx: ty::ctxt, def: ast::def_id) -> @[ty::method] {
let cstore = tcx.sess.get_cstore();
let cdata = cstore::get_crate_data(cstore, def.crate).data;
let resolver = bind translate_def_id(cstore, def.crate, _);
decoder::get_iface_methods(cdata, def, tcx, resolver)
let cdata = cstore::get_crate_data(cstore, def.crate);
decoder::get_iface_methods(cdata, def.node, tcx)
}
fn get_type(tcx: ty::ctxt, def: ast::def_id) -> ty::ty_param_bounds_and_ty {
let cstore = tcx.sess.get_cstore();
let cdata = cstore::get_crate_data(cstore, def.crate).data;
let resolver = bind translate_def_id(cstore, def.crate, _);
decoder::get_type(cdata, def, tcx, resolver)
let cdata = cstore::get_crate_data(cstore, def.crate);
decoder::get_type(cdata, def.node, tcx)
}
fn get_item_name(cstore: cstore::cstore, cnum: int, id: int) -> ast::ident {
@ -94,34 +89,8 @@ fn get_item_name(cstore: cstore::cstore, cnum: int, id: int) -> ast::ident {
fn get_impl_iface(tcx: ty::ctxt, def: ast::def_id)
-> option::t<ty::t> {
let cstore = tcx.sess.get_cstore();
let cdata = cstore::get_crate_data(cstore, def.crate).data;
let resolver = bind translate_def_id(cstore, def.crate, _);
decoder::get_impl_iface(cdata, def, tcx, resolver)
}
// Translates a def_id from an external crate to a def_id for the current
// compilation environment. We use this when trying to load types from
// external crates - if those types further refer to types in other crates
// then we must translate the crate number from that encoded in the external
// crate to the correct local crate number.
fn translate_def_id(cstore: cstore::cstore, searched_crate: ast::crate_num,
def_id: ast::def_id) -> ast::def_id {
let ext_cnum = def_id.crate;
let node_id = def_id.node;
assert (searched_crate != ast::local_crate);
assert (ext_cnum != ast::local_crate);
let cmeta = cstore::get_crate_data(cstore, searched_crate);
let local_cnum =
alt cmeta.cnum_map.find(ext_cnum) {
option::some(n) { n }
option::none. { fail "didn't find a crate in the cnum_map"; }
};
ret {crate: local_cnum, node: node_id};
let cdata = cstore::get_crate_data(cstore, def.crate);
decoder::get_impl_iface(cdata, def.node, tcx)
}
// Local Variables:

View File

@ -30,7 +30,10 @@ export get_dep_hashes;
// own crate numbers.
type cnum_map = map::hashmap<ast::crate_num, ast::crate_num>;
type crate_metadata = {name: str, data: @[u8], cnum_map: cnum_map};
type crate_metadata = @{name: str,
data: @[u8],
cnum_map: cnum_map,
cnum: ast::crate_num};
// This is a bit of an experiment at encapsulating the data in cstore. By
// keeping all the data in a non-exported tag variant, it's impossible for

View File

@ -1,14 +1,13 @@
// Decoding metadata from a single crate's metadata
import core::{vec, option, str};
import std::{ebml, io};
import syntax::{ast, ast_util};
import front::attr;
import middle::ty;
import common::*;
import tydecode::{parse_def_id, parse_ty_data};
import tydecode::{parse_ty_data, parse_def_id, parse_bounds_data};
import syntax::print::pprust;
import cstore;
import cmd=cstore::crate_metadata;
export get_symbol;
export get_tag_variants;
@ -24,7 +23,6 @@ export list_crate_metadata;
export crate_dep;
export get_crate_deps;
export get_crate_hash;
export external_resolver;
export get_impls_for_mod;
export get_iface_methods;
// A function that takes a def_id relative to the crate being searched and
@ -32,7 +30,6 @@ export get_iface_methods;
// def_id for an item defined in another crate, somebody needs to figure out
// what crate that's in and give us a def_id that makes sense for the current
// build.
type external_resolver = fn@(ast::def_id) -> ast::def_id;
fn lookup_hash(d: ebml::doc, eq_fn: fn@([u8]) -> bool, hash: uint) ->
[ebml::doc] {
@ -91,66 +88,50 @@ fn variant_tag_id(d: ebml::doc) -> ast::def_id {
ret parse_def_id(ebml::doc_data(tagdoc));
}
fn parse_external_def_id(this_cnum: ast::crate_num,
extres: external_resolver, s: str) ->
ast::def_id {
let buf = str::bytes(s);
let external_def_id = parse_def_id(buf);
// This item was defined in the crate we're searching if it's has the
// local crate number, otherwise we need to search a different crate
if external_def_id.crate == ast::local_crate {
ret {crate: this_cnum, node: external_def_id.node};
} else { ret extres(external_def_id); }
}
fn doc_type(doc: ebml::doc, this_cnum: ast::crate_num, tcx: ty::ctxt,
extres: external_resolver) -> ty::t {
fn doc_type(doc: ebml::doc, tcx: ty::ctxt, cdata: cmd) -> ty::t {
let tp = ebml::get_doc(doc, tag_items_data_item_type);
let def_parser = bind parse_external_def_id(this_cnum, extres, _);
parse_ty_data(tp.data, this_cnum, tp.start, def_parser, tcx)
parse_ty_data(tp.data, cdata.cnum, tp.start, tcx, {|did|
translate_def_id(cdata, did)
})
}
fn item_type(item: ebml::doc, this_cnum: ast::crate_num, tcx: ty::ctxt,
extres: external_resolver) -> ty::t {
let t = doc_type(item, this_cnum, tcx, extres);
fn item_type(item: ebml::doc, tcx: ty::ctxt, cdata: cmd) -> ty::t {
let t = doc_type(item, tcx, cdata);
if family_names_type(item_family(item)) {
ty::mk_named(tcx, t, @item_name(item))
} else { t }
}
fn item_impl_iface(item: ebml::doc, this_cnum: ast::crate_num, tcx: ty::ctxt,
extres: external_resolver) -> option::t<ty::t> {
fn item_impl_iface(item: ebml::doc, tcx: ty::ctxt, cdata: cmd)
-> option::t<ty::t> {
let result = none;
ebml::tagged_docs(item, tag_impl_iface) {|ity|
let def_parser = bind parse_external_def_id(this_cnum, extres, _);
let t = parse_ty_data(ity.data, this_cnum, ity.start, def_parser,
tcx);
let t = parse_ty_data(ity.data, cdata.cnum, ity.start, tcx, {|did|
translate_def_id(cdata, did)
});
result = some(t);
}
result
}
fn item_impl_iface_did(item: ebml::doc, this_cnum: ast::crate_num,
extres: external_resolver)
fn item_impl_iface_did(item: ebml::doc, cdata: cmd)
-> option::t<ast::def_id> {
let result = none;
ebml::tagged_docs(item, tag_impl_iface_did) {|doc|
let s = str::unsafe_from_bytes(ebml::doc_data(doc));
result = some(parse_external_def_id(this_cnum, extres, s));
let did = translate_def_id(cdata, parse_def_id(ebml::doc_data(doc)));
result = some(did);
}
result
}
fn item_ty_param_bounds(item: ebml::doc, this_cnum: ast::crate_num,
tcx: ty::ctxt, extres: external_resolver)
fn item_ty_param_bounds(item: ebml::doc, tcx: ty::ctxt, cdata: cmd)
-> @[ty::param_bounds] {
let bounds = [];
let def_parser = bind parse_external_def_id(this_cnum, extres, _);
ebml::tagged_docs(item, tag_items_data_item_ty_param_bounds) {|p|
bounds += [tydecode::parse_bounds_data(p.data, p.start,
this_cnum, def_parser, tcx)];
let bd = parse_bounds_data(p.data, p.start, cdata.cnum, tcx, {|did|
translate_def_id(cdata, did)
});
bounds += [bd];
}
@bounds
}
@ -162,13 +143,12 @@ fn item_ty_param_count(item: ebml::doc) -> uint {
n
}
fn tag_variant_ids(item: ebml::doc, this_cnum: ast::crate_num) ->
[ast::def_id] {
fn tag_variant_ids(item: ebml::doc, cdata: cmd) -> [ast::def_id] {
let ids: [ast::def_id] = [];
let v = tag_items_data_item_variant;
ebml::tagged_docs(item, v) {|p|
let ext = parse_def_id(ebml::doc_data(p));
ids += [{crate: this_cnum, node: ext.node}];
ids += [{crate: cdata.cnum, node: ext.node}];
};
ret ids;
}
@ -230,12 +210,12 @@ fn lookup_def(cnum: ast::crate_num, data: @[u8], did_: ast::def_id) ->
ret def;
}
fn get_type(data: @[u8], def: ast::def_id, tcx: ty::ctxt,
extres: external_resolver) -> ty::ty_param_bounds_and_ty {
let item = lookup_item(def.node, data);
let t = item_type(item, def.crate, tcx, extres);
fn get_type(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
-> ty::ty_param_bounds_and_ty {
let item = lookup_item(id, cdata.data);
let t = item_type(item, tcx, cdata);
let tp_bounds = if family_has_type_params(item_family(item)) {
item_ty_param_bounds(item, def.crate, tcx, extres)
item_ty_param_bounds(item, tcx, cdata)
} else { @[] };
ret {bounds: tp_bounds, ty: t};
}
@ -244,27 +224,25 @@ fn get_type_param_count(data: @[u8], id: ast::node_id) -> uint {
item_ty_param_count(lookup_item(id, data))
}
fn get_impl_iface(data: @[u8], def: ast::def_id, tcx: ty::ctxt,
extres: external_resolver) -> option::t<ty::t> {
item_impl_iface(lookup_item(def.node, data), def.crate, tcx, extres)
fn get_impl_iface(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
-> option::t<ty::t> {
item_impl_iface(lookup_item(id, cdata.data), tcx, cdata)
}
fn get_symbol(data: @[u8], id: ast::node_id) -> str {
ret item_symbol(lookup_item(id, data));
}
fn get_tag_variants(_data: @[u8], def: ast::def_id, tcx: ty::ctxt,
extres: external_resolver) -> [ty::variant_info] {
let external_crate_id = def.crate;
let data =
cstore::get_crate_data(tcx.sess.get_cstore(), external_crate_id).data;
fn get_tag_variants(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
-> [ty::variant_info] {
let data = cdata.data;
let items = ebml::get_doc(ebml::new_doc(data), tag_items);
let item = find_item(def.node, items);
let item = find_item(id, items);
let infos: [ty::variant_info] = [];
let variant_ids = tag_variant_ids(item, external_crate_id);
let variant_ids = tag_variant_ids(item, cdata);
for did: ast::def_id in variant_ids {
let item = find_item(did.node, items);
let ctor_ty = item_type(item, external_crate_id, tcx, extres);
let ctor_ty = item_type(item, tcx, cdata);
let arg_tys: [ty::t] = [];
alt ty::struct(tcx, ctor_ty) {
ty::ty_fn(f) {
@ -290,17 +268,17 @@ fn item_impl_methods(data: @[u8], item: ebml::doc, base_tps: uint)
rslt
}
fn get_impls_for_mod(data: @[u8], m_def: ast::def_id,
name: option::t<ast::ident>, extres: external_resolver)
fn get_impls_for_mod(cdata: cmd, m_id: ast::node_id,
name: option::t<ast::ident>)
-> @[@middle::resolve::_impl] {
let mod_item = lookup_item(m_def.node, data), result = [];
let data = cdata.data;
let mod_item = lookup_item(m_id, data), result = [];
ebml::tagged_docs(mod_item, tag_mod_impl) {|doc|
let did = parse_external_def_id(
m_def.crate, extres, str::unsafe_from_bytes(ebml::doc_data(doc)));
let did = translate_def_id(cdata, parse_def_id(ebml::doc_data(doc)));
let item = lookup_item(did.node, data), nm = item_name(item);
if alt name { some(n) { n == nm } none. { true } } {
let base_tps = item_ty_param_count(doc);
let i_did = item_impl_iface_did(item, m_def.crate, extres);
let i_did = item_impl_iface_did(item, cdata);
result += [@{did: did, iface_did: i_did, ident: nm,
methods: item_impl_methods(data, doc, base_tps)}];
}
@ -308,13 +286,14 @@ fn get_impls_for_mod(data: @[u8], m_def: ast::def_id,
@result
}
fn get_iface_methods(data: @[u8], def: ast::def_id, tcx: ty::ctxt,
extres: external_resolver) -> @[ty::method] {
let item = lookup_item(def.node, data), result = [];
fn get_iface_methods(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
-> @[ty::method] {
let data = cdata.data;
let item = lookup_item(id, data), result = [];
ebml::tagged_docs(item, tag_item_method) {|mth|
let bounds = item_ty_param_bounds(mth, def.crate, tcx, extres);
let bounds = item_ty_param_bounds(mth, tcx, cdata);
let name = item_name(mth);
let ty = doc_type(mth, def.crate, tcx, extres);
let ty = doc_type(mth, tcx, cdata);
let fty = alt ty::struct(tcx, ty) { ty::ty_fn(f) { f } };
result += [{ident: name, tps: bounds, fty: fty}];
}
@ -489,6 +468,22 @@ fn list_crate_metadata(bytes: @[u8], out: io::writer) {
list_crate_items(bytes, md, out);
}
// Translates a def_id from an external crate to a def_id for the current
// compilation environment. We use this when trying to load types from
// external crates - if those types further refer to types in other crates
// then we must translate the crate number from that encoded in the external
// crate to the correct local crate number.
fn translate_def_id(cdata: cmd, did: ast::def_id) -> ast::def_id {
if did.crate == ast::local_crate {
ret {crate: cdata.cnum, node: did.node};
}
alt cdata.cnum_map.find(did.crate) {
option::some(n) { ret {crate: n, node: did.node}; }
option::none. { fail "didn't find a crate in the cnum_map"; }
}
}
// Local Variables:
// mode: rust
// fill-column: 78;

View File

@ -492,7 +492,7 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer,
// Path and definition ID indexing
fn create_index<copy T>(index: [entry<T>], hash_fn: fn(T) -> uint) ->
fn create_index<T: copy>(index: [entry<T>], hash_fn: fn(T) -> uint) ->
[@[entry<T>]] {
let buckets: [@mutable [entry<T>]] = [];
uint::range(0u, 256u) {|_i| buckets += [@mutable []]; };

View File

@ -8,8 +8,7 @@ import syntax::ast_util;
import syntax::ast_util::respan;
import middle::ty;
export parse_def_id;
export parse_ty_data;
export parse_ty_data, parse_def_id;
export parse_bounds_data;
// Compact string representation for ty::t values. API ty_str &
@ -17,7 +16,7 @@ export parse_bounds_data;
// data buffer. Whatever format you choose should not contain pipe characters.
// Callback to translate defs to strs or back:
type str_def = fn@(str) -> ast::def_id;
type conv_did = block(ast::def_id) -> ast::def_id;
type pstate = {data: @[u8], crate: int, mutable pos: uint, tcx: ty::ctxt};
@ -31,12 +30,12 @@ fn next(st: @pstate) -> u8 {
ret ch;
}
fn parse_ident(st: @pstate, sd: str_def, last: char) -> ast::ident {
fn parse_ident(st: @pstate, last: char) -> ast::ident {
fn is_last(b: char, c: char) -> bool { ret c == b; }
ret parse_ident_(st, sd, bind is_last(last, _));
ret parse_ident_(st, bind is_last(last, _));
}
fn parse_ident_(st: @pstate, _sd: str_def, is_last: fn@(char) -> bool) ->
fn parse_ident_(st: @pstate, is_last: fn@(char) -> bool) ->
ast::ident {
let rslt = "";
while !is_last(peek(st) as char) {
@ -46,28 +45,26 @@ fn parse_ident_(st: @pstate, _sd: str_def, is_last: fn@(char) -> bool) ->
}
fn parse_ty_data(data: @[u8], crate_num: int, pos: uint, sd: str_def,
tcx: ty::ctxt) -> ty::t {
fn parse_ty_data(data: @[u8], crate_num: int, pos: uint, tcx: ty::ctxt,
conv: conv_did) -> ty::t {
let st = @{data: data, crate: crate_num, mutable pos: pos, tcx: tcx};
parse_ty(st, sd)
parse_ty(st, conv)
}
fn parse_ret_ty(st: @pstate, sd: str_def) -> (ast::ret_style, ty::t) {
fn parse_ret_ty(st: @pstate, conv: conv_did) -> (ast::ret_style, ty::t) {
alt peek(st) as char {
'!' { next(st); (ast::noreturn, ty::mk_bot(st.tcx)) }
_ { (ast::return_val, parse_ty(st, sd)) }
_ { (ast::return_val, parse_ty(st, conv)) }
}
}
fn parse_constrs(st: @pstate, sd: str_def) -> [@ty::constr] {
fn parse_constrs(st: @pstate, conv: conv_did) -> [@ty::constr] {
let rslt: [@ty::constr] = [];
alt peek(st) as char {
':' {
do {
next(st);
let one: @ty::constr =
parse_constr::<uint>(st, sd, parse_constr_arg);
rslt += [one];
rslt += [parse_constr(st, conv, parse_constr_arg)];
} while peek(st) as char == ';'
}
_ { }
@ -76,15 +73,13 @@ fn parse_constrs(st: @pstate, sd: str_def) -> [@ty::constr] {
}
// FIXME less copy-and-paste
fn parse_ty_constrs(st: @pstate, sd: str_def) -> [@ty::type_constr] {
fn parse_ty_constrs(st: @pstate, conv: conv_did) -> [@ty::type_constr] {
let rslt: [@ty::type_constr] = [];
alt peek(st) as char {
':' {
do {
next(st);
let one: @ty::type_constr =
parse_constr::<@path>(st, sd, parse_ty_constr_arg);
rslt += [one];
rslt += [parse_constr(st, conv, parse_ty_constr_arg)];
} while peek(st) as char == ';'
}
_ { }
@ -92,10 +87,10 @@ fn parse_ty_constrs(st: @pstate, sd: str_def) -> [@ty::type_constr] {
ret rslt;
}
fn parse_path(st: @pstate, sd: str_def) -> @ast::path {
fn parse_path(st: @pstate) -> @ast::path {
let idents: [ast::ident] = [];
fn is_last(c: char) -> bool { ret c == '(' || c == ':'; }
idents += [parse_ident_(st, sd, is_last)];
idents += [parse_ident_(st, is_last)];
while true {
alt peek(st) as char {
':' { next(st); next(st); }
@ -103,16 +98,14 @@ fn parse_path(st: @pstate, sd: str_def) -> @ast::path {
if c == '(' {
ret @respan(ast_util::dummy_sp(),
{global: false, idents: idents, types: []});
} else { idents += [parse_ident_(st, sd, is_last)]; }
} else { idents += [parse_ident_(st, is_last)]; }
}
}
}
fail "parse_path: ill-formed path";
}
type arg_parser<T> = fn(@pstate, str_def) -> ast::constr_arg_general_<T>;
fn parse_constr_arg(st: @pstate, _sd: str_def) -> ast::fn_constr_arg {
fn parse_constr_arg(st: @pstate) -> ast::fn_constr_arg {
alt peek(st) as char {
'*' { st.pos += 1u; ret ast::carg_base; }
c {
@ -129,7 +122,7 @@ fn parse_constr_arg(st: @pstate, _sd: str_def) -> ast::fn_constr_arg {
}
/*
else {
auto lit = parse_lit(st, sd, ',');
auto lit = parse_lit(st, conv, ',');
args += [respan(st.span, ast::carg_lit(lit))];
}
*/
@ -137,25 +130,25 @@ fn parse_constr_arg(st: @pstate, _sd: str_def) -> ast::fn_constr_arg {
}
}
fn parse_ty_constr_arg(st: @pstate, sd: str_def) ->
ast::constr_arg_general_<@path> {
fn parse_ty_constr_arg(st: @pstate) -> ast::constr_arg_general_<@path> {
alt peek(st) as char {
'*' { st.pos += 1u; ret ast::carg_base; }
c { ret ast::carg_ident(parse_path(st, sd)); }
c { ret ast::carg_ident(parse_path(st)); }
}
}
fn parse_constr<copy T>(st: @pstate, sd: str_def, pser: arg_parser<T>) ->
@ty::constr_general<T> {
fn parse_constr<T: copy>(st: @pstate, conv: conv_did,
pser: block(@pstate) -> ast::constr_arg_general_<T>)
-> @ty::constr_general<T> {
let sp = ast_util::dummy_sp(); // FIXME: use a real span
let args: [@sp_constr_arg<T>] = [];
let pth = parse_path(st, sd);
let pth = parse_path(st);
let ignore: char = next(st) as char;
assert (ignore == '(');
let def = parse_def(st, sd);
let def = parse_def(st, conv);
let an_arg: constr_arg_general_<T>;
do {
an_arg = pser(st, sd);
an_arg = pser(st);
// FIXME use a real span
args += [@respan(sp, an_arg)];
ignore = next(st) as char;
@ -164,11 +157,11 @@ fn parse_constr<copy T>(st: @pstate, sd: str_def, pser: arg_parser<T>) ->
ret @respan(sp, {path: pth, args: args, id: def});
}
fn parse_ty_rust_fn(st: @pstate, sd: str_def, p: ast::proto) -> ty::t {
ret ty::mk_fn(st.tcx, {proto: p with parse_ty_fn(st, sd)});
fn parse_ty_rust_fn(st: @pstate, conv: conv_did, p: ast::proto) -> ty::t {
ret ty::mk_fn(st.tcx, {proto: p with parse_ty_fn(st, conv)});
}
fn parse_ty(st: @pstate, sd: str_def) -> ty::t {
fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
alt next(st) as char {
'n' { ret ty::mk_nil(st.tcx); }
'z' { ret ty::mk_bot(st.tcx); }
@ -194,28 +187,28 @@ fn parse_ty(st: @pstate, sd: str_def) -> ty::t {
'S' { ret ty::mk_str(st.tcx); }
't' {
assert (next(st) as char == '[');
let def = parse_def(st, sd);
let def = parse_def(st, conv);
let params: [ty::t] = [];
while peek(st) as char != ']' { params += [parse_ty(st, sd)]; }
while peek(st) as char != ']' { params += [parse_ty(st, conv)]; }
st.pos = st.pos + 1u;
ret ty::mk_tag(st.tcx, def, params);
}
'x' {
assert (next(st) as char == '[');
let def = parse_def(st, sd);
let def = parse_def(st, conv);
let params: [ty::t] = [];
while peek(st) as char != ']' { params += [parse_ty(st, sd)]; }
while peek(st) as char != ']' { params += [parse_ty(st, conv)]; }
st.pos = st.pos + 1u;
ret ty::mk_iface(st.tcx, def, params);
}
'p' {
let did = parse_def(st, sd);
let did = parse_def(st, conv);
ret ty::mk_param(st.tcx, parse_int(st) as uint, did);
}
'@' { ret ty::mk_box(st.tcx, parse_mt(st, sd)); }
'~' { ret ty::mk_uniq(st.tcx, parse_mt(st, sd)); }
'*' { ret ty::mk_ptr(st.tcx, parse_mt(st, sd)); }
'I' { ret ty::mk_vec(st.tcx, parse_mt(st, sd)); }
'@' { ret ty::mk_box(st.tcx, parse_mt(st, conv)); }
'~' { ret ty::mk_uniq(st.tcx, parse_mt(st, conv)); }
'*' { ret ty::mk_ptr(st.tcx, parse_mt(st, conv)); }
'I' { ret ty::mk_vec(st.tcx, parse_mt(st, conv)); }
'R' {
assert (next(st) as char == '[');
let fields: [ty::field] = [];
@ -225,7 +218,7 @@ fn parse_ty(st: @pstate, sd: str_def) -> ty::t {
name += str::unsafe_from_byte(next(st));
}
st.pos = st.pos + 1u;
fields += [{ident: name, mt: parse_mt(st, sd)}];
fields += [{ident: name, mt: parse_mt(st, conv)}];
}
st.pos = st.pos + 1u;
ret ty::mk_rec(st.tcx, fields);
@ -233,24 +226,24 @@ fn parse_ty(st: @pstate, sd: str_def) -> ty::t {
'T' {
assert (next(st) as char == '[');
let params = [];
while peek(st) as char != ']' { params += [parse_ty(st, sd)]; }
while peek(st) as char != ']' { params += [parse_ty(st, conv)]; }
st.pos = st.pos + 1u;
ret ty::mk_tup(st.tcx, params);
}
's' {
ret parse_ty_rust_fn(st, sd, ast::proto_send);
ret parse_ty_rust_fn(st, conv, ast::proto_send);
}
'F' {
ret parse_ty_rust_fn(st, sd, ast::proto_shared(ast::sugar_normal));
ret parse_ty_rust_fn(st, conv, ast::proto_shared(ast::sugar_normal));
}
'f' {
ret parse_ty_rust_fn(st, sd, ast::proto_bare);
ret parse_ty_rust_fn(st, conv, ast::proto_bare);
}
'B' {
ret parse_ty_rust_fn(st, sd, ast::proto_block);
ret parse_ty_rust_fn(st, conv, ast::proto_block);
}
'N' {
let func = parse_ty_fn(st, sd);
let func = parse_ty_fn(st, conv);
ret ty::mk_native_fn(st.tcx, func.inputs, func.output);
}
'O' {
@ -266,22 +259,22 @@ fn parse_ty(st: @pstate, sd: str_def) -> ty::t {
name += str::unsafe_from_byte(next(st));
}
methods += [{ident: name, tps: @[],
fty: {proto: proto with parse_ty_fn(st, sd)}}];
fty: {proto: proto with parse_ty_fn(st, conv)}}];
}
st.pos += 1u;
ret ty::mk_obj(st.tcx, methods);
}
'r' {
assert (next(st) as char == '[');
let def = parse_def(st, sd);
let inner = parse_ty(st, sd);
let def = parse_def(st, conv);
let inner = parse_ty(st, conv);
let params: [ty::t] = [];
while peek(st) as char != ']' { params += [parse_ty(st, sd)]; }
while peek(st) as char != ']' { params += [parse_ty(st, conv)]; }
st.pos = st.pos + 1u;
ret ty::mk_res(st.tcx, def, inner, params);
}
'X' { ret ty::mk_var(st.tcx, parse_int(st)); }
'E' { let def = parse_def(st, sd); ret ty::mk_native(st.tcx, def); }
'E' { let def = parse_def(st, conv); ret ty::mk_native(st.tcx, def); }
'Y' { ret ty::mk_type(st.tcx); }
'y' { ret ty::mk_send_type(st.tcx); }
'C' { ret ty::mk_opaque_closure(st.tcx); }
@ -294,7 +287,7 @@ fn parse_ty(st: @pstate, sd: str_def) -> ty::t {
some(tt) { ret tt; }
none. {
let ps = @{pos: pos with *st};
let tt = parse_ty(ps, sd);
let tt = parse_ty(ps, conv);
st.tcx.rcache.insert({cnum: st.crate, pos: pos, len: len}, tt);
ret tt;
}
@ -302,8 +295,8 @@ fn parse_ty(st: @pstate, sd: str_def) -> ty::t {
}
'A' {
assert (next(st) as char == '[');
let tt = parse_ty(st, sd);
let tcs = parse_ty_constrs(st, sd);
let tt = parse_ty(st, conv);
let tcs = parse_ty_constrs(st, conv);
assert (next(st) as char == ']');
ret ty::mk_constr(st.tcx, tt, tcs);
}
@ -311,21 +304,21 @@ fn parse_ty(st: @pstate, sd: str_def) -> ty::t {
}
}
fn parse_mt(st: @pstate, sd: str_def) -> ty::mt {
fn parse_mt(st: @pstate, conv: conv_did) -> ty::mt {
let mut;
alt peek(st) as char {
'm' { next(st); mut = ast::mut; }
'?' { next(st); mut = ast::maybe_mut; }
_ { mut = ast::imm; }
}
ret {ty: parse_ty(st, sd), mut: mut};
ret {ty: parse_ty(st, conv), mut: mut};
}
fn parse_def(st: @pstate, sd: str_def) -> ast::def_id {
let def = "";
while peek(st) as char != '|' { def += str::unsafe_from_byte(next(st)); }
fn parse_def(st: @pstate, conv: conv_did) -> ast::def_id {
let def = [];
while peek(st) as char != '|' { def += [next(st)]; }
st.pos = st.pos + 1u;
ret sd(def);
ret conv(parse_def_id(def));
}
fn parse_int(st: @pstate) -> int {
@ -354,7 +347,7 @@ fn parse_hex(st: @pstate) -> uint {
ret n;
}
fn parse_ty_fn(st: @pstate, sd: str_def) -> ty::fn_ty {
fn parse_ty_fn(st: @pstate, conv: conv_did) -> ty::fn_ty {
assert (next(st) as char == '[');
let inputs: [ty::arg] = [];
while peek(st) as char != ']' {
@ -366,11 +359,11 @@ fn parse_ty_fn(st: @pstate, sd: str_def) -> ty::fn_ty {
'#' { ast::by_val }
};
st.pos += 1u;
inputs += [{mode: mode, ty: parse_ty(st, sd)}];
inputs += [{mode: mode, ty: parse_ty(st, conv)}];
}
st.pos += 1u; // eat the ']'
let cs = parse_constrs(st, sd);
let (ret_style, ret_ty) = parse_ret_ty(st, sd);
let cs = parse_constrs(st, conv);
let (ret_style, ret_ty) = parse_ret_ty(st, conv);
ret {proto: ast::proto_bare, inputs: inputs, output: ret_ty,
ret_style: ret_style, constraints: cs};
}
@ -399,19 +392,19 @@ fn parse_def_id(buf: [u8]) -> ast::def_id {
}
fn parse_bounds_data(data: @[u8], start: uint,
crate_num: int, sd: str_def, tcx: ty::ctxt)
crate_num: int, tcx: ty::ctxt, conv: conv_did)
-> @[ty::param_bound] {
let st = @{data: data, crate: crate_num, mutable pos: start, tcx: tcx};
parse_bounds(st, sd)
parse_bounds(st, conv)
}
fn parse_bounds(st: @pstate, sd: str_def) -> @[ty::param_bound] {
fn parse_bounds(st: @pstate, conv: conv_did) -> @[ty::param_bound] {
let bounds = [];
while true {
bounds += [alt next(st) as char {
'S' { ty::bound_send }
'C' { ty::bound_copy }
'I' { ty::bound_iface(parse_ty(st, sd)) }
'I' { ty::bound_iface(parse_ty(st, conv)) }
'.' { break; }
}];
}

View File

@ -98,7 +98,7 @@ fn map_expr(cx: ctx, ex: @expr) {
}
}
fn new_smallintmap_int_adapter<copy V>() -> std::map::hashmap<int, V> {
fn new_smallintmap_int_adapter<V: copy>() -> std::map::hashmap<int, V> {
let key_idx = fn (&&key: int) -> uint { key as uint };
let idx_key = fn (idx: uint) -> int { idx as int };
ret new_smallintmap_adapter(key_idx, idx_key);
@ -109,11 +109,11 @@ fn new_smallintmap_int_adapter<copy V>() -> std::map::hashmap<int, V> {
// the entire codebase adapting all the callsites to the different
// interface.
// FIXME: hashmap and smallintmap should support the same interface.
fn new_smallintmap_adapter<copy K, copy V>(key_idx: fn(K) -> uint,
fn new_smallintmap_adapter<K: copy, V: copy>(key_idx: fn(K) -> uint,
idx_key: fn(uint) -> K)
-> std::map::hashmap<K, V> {
obj adapter<copy K, copy V>(map: smallintmap::smallintmap<V>,
obj adapter<K: copy, V: copy>(map: smallintmap::smallintmap<V>,
key_idx: fn(K) -> uint,
idx_key: fn(uint) -> K) {

View File

@ -118,7 +118,7 @@ tag debug_metadata {
retval_metadata(@metadata<retval_md>);
}
fn cast_safely<copy T, U>(val: T) -> U unsafe {
fn cast_safely<T: copy, U>(val: T) -> U unsafe {
let val2 = val;
let val3 = unsafe::reinterpret_cast(val2);
unsafe::leak(val2);
@ -138,7 +138,7 @@ fn md_from_metadata<T>(val: debug_metadata) -> T unsafe {
}
}
fn cached_metadata<copy T>(cache: metadata_cache, mdtag: int,
fn cached_metadata<T: copy>(cache: metadata_cache, mdtag: int,
eq: block(md: T) -> bool) -> option::t<T> unsafe {
if cache.contains_key(mdtag) {
let items = cache.get(mdtag);

View File

@ -5354,7 +5354,7 @@ fn collect_item(ccx: @crate_ctxt, abi: @mutable option::t<ast::native_abi>,
register_fn(ccx, i.span, new_pt, "obj_ctor", tps, ctor_id);
}
ast::item_impl(tps, _, _, methods) {
let name = ccx.names.next(i.ident);
let name = i.ident + int::str(i.id);
for m in methods {
register_fn(ccx, i.span, pt + [name, m.ident],
"impl_method", tps + m.tps, m.id);
@ -5418,9 +5418,7 @@ fn trans_constant(ccx: @crate_ctxt, it: @ast::item, &&pt: [str],
ast::item_impl(tps, some(@{node: ast::ty_path(_, id), _}), _, ms) {
let i_did = ast_util::def_id_of_def(ccx.tcx.def_map.get(id));
let ty = ty::lookup_item_type(ccx.tcx, i_did).ty;
// FIXME[impl] use the same name as used in collect_items, for
// slightly more consistent symbol names?
let new_pt = pt + [ccx.names.next(it.ident)];
let new_pt = pt + [it.ident + int::str(it.id), "wrap"];
let extra_tps = vec::map(tps, {|p| param_bounds(ccx, p)});
let tbl = C_struct(vec::map(*ty::iface_methods(ccx.tcx, i_did), {|im|
alt vec::find(ms, {|m| m.ident == im.ident}) {

View File

@ -414,7 +414,7 @@ fn mk_rcache() -> creader_cache {
ret map::mk_hashmap(hash_cache_entry, eq_cache_entries);
}
fn new_ty_hash<copy V>() -> map::hashmap<t, V> { map::new_uint_hash() }
fn new_ty_hash<V: copy>() -> map::hashmap<t, V> { map::new_uint_hash() }
fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map,
freevars: freevars::freevar_map) -> ctxt {

View File

@ -2920,8 +2920,6 @@ mod dict {
bind_params(fcx, self_ty, n_tps)
} else { {vars: [], ty: self_ty} };
let im_bs = ty::lookup_item_type(tcx, im.did).bounds;
// FIXME[impl] don't do this in fcx (or make
// unify transactional by scrubbing bindings on fail)
alt unify::unify(fcx, ty, self_ty) {
ures_ok(_) {
if option::is_some(found) {

View File

@ -1,7 +1,7 @@
import codemap::span;
import ast::*;
fn respan<copy T>(sp: span, t: T) -> spanned<T> {
fn respan<T: copy>(sp: span, t: T) -> spanned<T> {
ret {node: t, span: sp};
}
@ -201,7 +201,7 @@ fn eq_def_id(&&a: def_id, &&b: def_id) -> bool {
a == b
}
fn new_def_id_hash<copy T>() -> std::map::hashmap<def_id, T> {
fn new_def_id_hash<T: copy>() -> std::map::hashmap<def_id, T> {
std::map::mk_hashmap(hash_def_id, eq_def_id)
}

View File

@ -103,7 +103,7 @@ fn elts_to_ell(cx: ext_ctxt, elts: [@expr]) ->
}
}
fn option_flatten_map<copy T, copy U>(f: fn@(T) -> option::t<U>, v: [T]) ->
fn option_flatten_map<T: copy, U: copy>(f: fn@(T) -> option::t<U>, v: [T]) ->
option::t<[U]> {
let res = [];
for elem: T in v {

View File

@ -210,7 +210,7 @@ fn expect_gt(p: parser) {
}
}
fn spanned<copy T>(lo: uint, hi: uint, node: T) -> spanned<T> {
fn spanned<T: copy>(lo: uint, hi: uint, node: T) -> spanned<T> {
ret {node: node, span: ast_util::mk_sp(lo, hi)};
}
@ -378,7 +378,7 @@ fn parse_constr_in_type(p: parser) -> @ast::ty_constr {
}
fn parse_constrs<copy T>(pser: block(parser) -> @ast::constr_general<T>,
fn parse_constrs<T: copy>(pser: block(parser) -> @ast::constr_general<T>,
p: parser) ->
[@ast::constr_general<T>] {
let constrs: [@ast::constr_general<T>] = [];
@ -554,7 +554,7 @@ fn parse_fn_block_arg(p: parser) -> ast::arg {
ret {mode: m, ty: t, ident: i, id: p.get_id()};
}
fn parse_seq_to_before_gt<copy T>(sep: option::t<token::token>,
fn parse_seq_to_before_gt<T: copy>(sep: option::t<token::token>,
f: block(parser) -> T,
p: parser) -> [T] {
let first = true;
@ -571,7 +571,7 @@ fn parse_seq_to_before_gt<copy T>(sep: option::t<token::token>,
ret v;
}
fn parse_seq_to_gt<copy T>(sep: option::t<token::token>,
fn parse_seq_to_gt<T: copy>(sep: option::t<token::token>,
f: block(parser) -> T, p: parser) -> [T] {
let v = parse_seq_to_before_gt(sep, f, p);
expect_gt(p);
@ -579,7 +579,7 @@ fn parse_seq_to_gt<copy T>(sep: option::t<token::token>,
ret v;
}
fn parse_seq_lt_gt<copy T>(sep: option::t<token::token>,
fn parse_seq_lt_gt<T: copy>(sep: option::t<token::token>,
f: block(parser) -> T,
p: parser) -> spanned<[T]> {
let lo = p.get_lo_pos();
@ -590,7 +590,7 @@ fn parse_seq_lt_gt<copy T>(sep: option::t<token::token>,
ret spanned(lo, hi, result);
}
fn parse_seq_to_end<copy T>(ket: token::token, sep: seq_sep,
fn parse_seq_to_end<T: copy>(ket: token::token, sep: seq_sep,
f: block(parser) -> T, p: parser) -> [T] {
let val = parse_seq_to_before_end(ket, sep, f, p);
p.bump();
@ -612,7 +612,7 @@ fn seq_sep_none() -> seq_sep {
ret {sep: option::none, trailing_opt: false};
}
fn parse_seq_to_before_end<copy T>(ket: token::token,
fn parse_seq_to_before_end<T: copy>(ket: token::token,
sep: seq_sep,
f: block(parser) -> T, p: parser) -> [T] {
let first: bool = true;
@ -629,7 +629,7 @@ fn parse_seq_to_before_end<copy T>(ket: token::token,
}
fn parse_seq<copy T>(bra: token::token, ket: token::token,
fn parse_seq<T: copy>(bra: token::token, ket: token::token,
sep: seq_sep, f: block(parser) -> T,
p: parser) -> spanned<[T]> {
let lo = p.get_lo_pos();
@ -1700,8 +1700,6 @@ fn parse_block_tail(p: parser, lo: uint, s: ast::blk_check_mode) -> ast::blk {
fn parse_ty_param(p: parser) -> ast::ty_param {
let bounds = [];
if eat_word(p, "send") { bounds += [ast::bound_send]; }
else if eat_word(p, "copy") { bounds += [ast::bound_copy]; }
let ident = parse_ident(p);
if eat(p, token::COLON) {
while p.peek() != token::COMMA && p.peek() != token::GT {

View File

@ -12,12 +12,12 @@ type interner<T> =
hasher: hashfn<T>,
eqer: eqfn<T>};
fn mk<copy T>(hasher: hashfn<T>, eqer: eqfn<T>) -> interner<T> {
fn mk<T: copy>(hasher: hashfn<T>, eqer: eqfn<T>) -> interner<T> {
let m = map::mk_hashmap::<T, uint>(hasher, eqer);
ret {map: m, mutable vect: [], hasher: hasher, eqer: eqer};
}
fn intern<copy T>(itr: interner<T>, val: T) -> uint {
fn intern<T: copy>(itr: interner<T>, val: T) -> uint {
alt itr.map.find(val) {
some(idx) { ret idx; }
none. {
@ -32,7 +32,7 @@ fn intern<copy T>(itr: interner<T>, val: T) -> uint {
// |get| isn't "pure" in the traditional sense, because it can go from
// failing to returning a value as items are interned. But for typestate,
// where we first check a pred and then rely on it, ceasing to fail is ok.
pure fn get<copy T>(itr: interner<T>, idx: uint) -> T {
pure fn get<T: copy>(itr: interner<T>, idx: uint) -> T {
unchecked {
itr.vect[idx]
}

View File

@ -20,7 +20,7 @@ fn hash_def(d: ast::def_id) -> uint {
ret h;
}
fn new_def_hash<copy V>() -> std::map::hashmap<ast::def_id, V> {
fn new_def_hash<V: copy>() -> std::map::hashmap<ast::def_id, V> {
let hasher: std::map::hashfn<ast::def_id> = hash_def;
let eqer: std::map::eqfn<ast::def_id> = def_eq;
ret std::map::mk_hashmap::<ast::def_id, V>(hasher, eqer);

View File

@ -55,7 +55,7 @@ fn mk_filesearch(maybe_sysroot: option::t<fs::path>,
}
// FIXME #1001: This can't be an obj method
fn search<copy T>(filesearch: filesearch, pick: pick<T>) -> option::t<T> {
fn search<T: copy>(filesearch: filesearch, pick: pick<T>) -> option::t<T> {
for lib_search_path in filesearch.lib_search_paths() {
#debug("searching %s", lib_search_path);
for path in fs::list_dir(lib_search_path) {

View File

@ -225,7 +225,7 @@ fn check_variants_of_ast(crate: ast::crate, codemap: codemap::codemap,
check_variants_T(crate, codemap, filename, "ty", stolen.tys, pprust::ty_to_str, replace_ty_in_crate, cx);
}
fn check_variants_T<copy T>(
fn check_variants_T<T: copy>(
crate: ast::crate,
codemap: codemap::codemap,
filename: str,

View File

@ -39,7 +39,7 @@ native mod rustrt {
type void;
type rust_port;
fn chan_id_send<send T>(t: *sys::type_desc,
fn chan_id_send<T: send>(t: *sys::type_desc,
target_task: task::task, target_port: port_id,
data: T) -> ctypes::uintptr_t;
@ -55,7 +55,7 @@ native mod rustrt {
#[abi = "rust-intrinsic"]
native mod rusti {
fn call_with_retptr<send T>(&&f: fn@(*uint)) -> T;
fn call_with_retptr<T: send>(&&f: fn@(*uint)) -> T;
}
type port_id = int;
@ -78,11 +78,11 @@ dropped.
Channels may be duplicated and themselves transmitted over other channels.
*/
tag chan<send T> {
tag chan<T: send> {
chan_t(task::task, port_id);
}
resource port_ptr<send T>(po: *rustrt::rust_port) {
resource port_ptr<T: send>(po: *rustrt::rust_port) {
// Once the port is detached it's guaranteed not to receive further
// messages
rustrt::rust_port_detach(po);
@ -106,7 +106,7 @@ transmitted. If a port value is copied, both copies refer to the same port.
Ports may be associated with multiple <chan>s.
*/
tag port<send T> { port_t(@port_ptr<T>); }
tag port<T: send> { port_t(@port_ptr<T>); }
/*
Function: send
@ -116,7 +116,7 @@ Sends data over a channel.
The sent data is moved into the channel, whereupon the caller loses access
to it.
*/
fn send<send T>(ch: chan<T>, -data: T) {
fn send<T: send>(ch: chan<T>, -data: T) {
let chan_t(t, p) = ch;
let res = rustrt::chan_id_send(sys::get_type_desc::<T>(), t, p, data);
if res != 0u unsafe {
@ -131,7 +131,7 @@ Function: port
Constructs a port.
*/
fn port<send T>() -> port<T> {
fn port<T: send>() -> port<T> {
port_t(@port_ptr(rustrt::new_port(sys::size_of::<T>())))
}
@ -143,10 +143,10 @@ Receive from a port.
If no data is available on the port then the task will block until data
becomes available.
*/
fn recv<send T>(p: port<T>) -> T { recv_(***p) }
fn recv<T: send>(p: port<T>) -> T { recv_(***p) }
// Receive on a raw port pointer
fn recv_<send T>(p: *rustrt::rust_port) -> T {
fn recv_<T: send>(p: *rustrt::rust_port) -> T {
// FIXME: Due to issue 1185 we can't use a return pointer when
// calling C code, and since we can't create our own return
// pointer on the stack, we're going to call a little intrinsic
@ -179,6 +179,6 @@ Constructs a channel.
The channel is bound to the port used to construct it.
*/
fn chan<send T>(p: port<T>) -> chan<T> {
fn chan<T: send>(p: port<T>) -> chan<T> {
chan_t(task::get_task(), rustrt::get_port_id(***p))
}

View File

@ -39,7 +39,7 @@ Function: lefts
Extracts from a vector of either all the left values.
*/
fn lefts<copy T, U>(eithers: [t<T, U>]) -> [T] {
fn lefts<T: copy, U>(eithers: [t<T, U>]) -> [T] {
let result: [T] = [];
for elt: t<T, U> in eithers {
alt elt { left(l) { result += [l]; } _ {/* fallthrough */ } }
@ -52,7 +52,7 @@ Function: rights
Extracts from a vector of either all the right values
*/
fn rights<T, copy U>(eithers: [t<T, U>]) -> [U] {
fn rights<T, U: copy>(eithers: [t<T, U>]) -> [U] {
let result: [U] = [];
for elt: t<T, U> in eithers {
alt elt { right(r) { result += [r]; } _ {/* fallthrough */ } }
@ -68,7 +68,7 @@ Extracts from a vector of either all the left values and right values
Returns a structure containing a vector of left values and a vector of
right values.
*/
fn partition<copy T, copy U>(eithers: [t<T, U>])
fn partition<T: copy, U: copy>(eithers: [t<T, U>])
-> {lefts: [T], rights: [U]} {
let lefts: [T] = [];
let rights: [U] = [];
@ -83,7 +83,7 @@ Function: flip
Flips between left and right of a given either
*/
pure fn flip<copy T, copy U>(eith: t<T, U>) -> t<U, T> {
pure fn flip<T: copy, U: copy>(eith: t<T, U>) -> t<U, T> {
alt eith {
right(r) { left(r) }
left(l) { right(l) }
@ -96,7 +96,7 @@ Function: to_result
Converts either::t to a result::t, making the "right" choice
an ok result, and the "left" choice a fail
*/
pure fn to_result<copy T, copy U>(eith: t<T, U>) -> result::t<U, T> {
pure fn to_result<T: copy, U: copy>(eith: t<T, U>) -> result::t<U, T> {
alt eith {
right(r) { result::ok(r) }
left(l) { result::err(l) }

View File

@ -7,12 +7,12 @@ Function: min
Returns the minimum of two values
*/
pure fn min<copy T>(x: T, y: T) -> T { x < y ? x : y }
pure fn min<T: copy>(x: T, y: T) -> T { x < y ? x : y }
/*
Function: max
Returns the maximum of two values
*/
pure fn max<copy T>(x: T, y: T) -> T { x < y ? y : x }
pure fn max<T: copy>(x: T, y: T) -> T { x < y ? y : x }

View File

@ -30,13 +30,13 @@ Failure:
Fails if the value equals `none`.
*/
pure fn get<copy T>(opt: t<T>) -> T {
pure fn get<T: copy>(opt: t<T>) -> T {
alt opt { some(x) { ret x; } none. { fail "option none"; } }
}
/*
*/
fn map<T, copy U>(opt: t<T>, f: block(T) -> U) -> t<U> {
fn map<T, U: copy>(opt: t<T>, f: block(T) -> U) -> t<U> {
alt opt { some(x) { some(f(x)) } none. { none } }
}
@ -61,7 +61,7 @@ Function: from_maybe
Returns the contained value or a default
*/
pure fn from_maybe<copy T>(def: T, opt: t<T>) -> T {
pure fn from_maybe<T: copy>(def: T, opt: t<T>) -> T {
alt opt { some(x) { x } none. { def } }
}
@ -70,7 +70,7 @@ Function: maybe
Applies a function to the contained value or returns a default
*/
fn maybe<T, copy U>(def: U, opt: t<T>, f: block(T) -> U) -> U {
fn maybe<T, U: copy>(def: U, opt: t<T>, f: block(T) -> U) -> U {
alt opt { none. { def } some(t) { f(t) } }
}

View File

@ -37,7 +37,7 @@ Failure:
If the result is an error
*/
fn get<copy T, U>(res: t<T, U>) -> T {
fn get<T: copy, U>(res: t<T, U>) -> T {
alt res {
ok(t) { t }
err(_) {
@ -57,7 +57,7 @@ Failure:
If the result is not an error
*/
fn get_err<T, copy U>(res: t<T, U>) -> U {
fn get_err<T, U: copy>(res: t<T, U>) -> U {
alt res {
err(u) { u }
ok(_) {
@ -87,7 +87,7 @@ pure fn failure<T, U>(res: t<T, U>) -> bool {
!success(res)
}
pure fn to_either<copy T, copy U>(res: t<U, T>) -> either::t<T, U> {
pure fn to_either<T: copy, U: copy>(res: t<U, T>) -> either::t<T, U> {
alt res {
ok(res) { either::right(res) }
err(fail_) { either::left(fail_) }
@ -110,7 +110,7 @@ Example:
> })
*/
fn chain<T, copy U, copy V>(res: t<T, V>, op: block(T) -> t<U, V>)
fn chain<T, U: copy, V: copy>(res: t<T, V>, op: block(T) -> t<U, V>)
-> t<U, V> {
alt res {
ok(t) { op(t) }

View File

@ -236,7 +236,7 @@ Returns:
A handle to the new task
*/
fn spawn<send T>(-data: T, f: fn(T)) -> task {
fn spawn<T: send>(-data: T, f: fn(T)) -> task {
spawn_inner(data, f, none)
}
@ -249,7 +249,7 @@ termination
Immediately before termination, either on success or failure, the spawned
task will send a <task_notification> message on the provided channel.
*/
fn spawn_notify<send T>(-data: T, f: fn(T),
fn spawn_notify<T: send>(-data: T, f: fn(T),
notify: comm::chan<task_notification>) -> task {
spawn_inner(data, f, some(notify))
}
@ -263,7 +263,7 @@ This is a convenience wrapper around spawn_notify which, when paired
with <join> can be easily used to spawn a task then wait for it to
complete.
*/
fn spawn_joinable<send T>(-data: T, f: fn(T)) -> joinable_task {
fn spawn_joinable<T: send>(-data: T, f: fn(T)) -> joinable_task {
let p = comm::port::<task_notification>();
let id = spawn_notify(data, f, comm::chan::<task_notification>(p));
ret (id, p);
@ -279,11 +279,11 @@ fn spawn_joinable<send T>(-data: T, f: fn(T)) -> joinable_task {
//
// After the transition this should all be rewritten.
fn spawn_inner<send T>(-data: T, f: fn(T),
fn spawn_inner<T: send>(-data: T, f: fn(T),
notify: option<comm::chan<task_notification>>)
-> task unsafe {
fn wrapper<send T>(data: *u8, f: fn(T)) unsafe {
fn wrapper<T: send>(data: *u8, f: fn(T)) unsafe {
let data: ~T = unsafe::reinterpret_cast(data);
f(*data);
}

View File

@ -121,7 +121,7 @@ Creates and initializes an immutable vector.
Creates an immutable vector of size `n_elts` and initializes the elements
to the value `t`.
*/
fn init_elt<copy T>(t: T, n_elts: uint) -> [T] {
fn init_elt<T: copy>(t: T, n_elts: uint) -> [T] {
let v = [];
reserve(v, n_elts);
let i: uint = 0u;
@ -138,7 +138,7 @@ Creates and initializes a mutable vector.
Creates a mutable vector of size `n_elts` and initializes the elements
to the value `t`.
*/
fn init_elt_mut<copy T>(t: T, n_elts: uint) -> [mutable T] {
fn init_elt_mut<T: copy>(t: T, n_elts: uint) -> [mutable T] {
let v = [mutable];
reserve(v, n_elts);
let i: uint = 0u;
@ -153,7 +153,7 @@ Function: to_mut
Produces a mutable vector from an immutable vector.
*/
fn to_mut<copy T>(v: [T]) -> [mutable T] {
fn to_mut<T: copy>(v: [T]) -> [mutable T] {
let vres = [mutable];
for t: T in v { vres += [mutable t]; }
ret vres;
@ -165,7 +165,7 @@ Function: from_mut
Produces an immutable vector from a mutable vector.
*/
fn from_mut<copy T>(v: [mutable T]) -> [T] {
fn from_mut<T: copy>(v: [mutable T]) -> [T] {
let vres = [];
for t: T in v { vres += [t]; }
ret vres;
@ -181,7 +181,7 @@ Returns the first element of a vector
Predicates:
<is_not_empty> (v)
*/
pure fn head<copy T>(v: [const T]) : is_not_empty(v) -> T { ret v[0]; }
pure fn head<T: copy>(v: [const T]) : is_not_empty(v) -> T { ret v[0]; }
/*
Function: tail
@ -191,7 +191,7 @@ Returns all but the first element of a vector
Predicates:
<is_not_empty> (v)
*/
fn tail<copy T>(v: [const T]) : is_not_empty(v) -> [T] {
fn tail<T: copy>(v: [const T]) : is_not_empty(v) -> [T] {
ret slice(v, 1u, len(v));
}
@ -206,7 +206,7 @@ Returns all but the last elemnt of a vector
Preconditions:
`v` is not empty
*/
fn init<copy T>(v: [const T]) -> [T] {
fn init<T: copy>(v: [const T]) -> [T] {
assert len(v) != 0u;
slice(v, 0u, len(v) - 1u)
}
@ -221,7 +221,7 @@ Returns:
An option containing the last element of `v` if `v` is not empty, or
none if `v` is empty.
*/
pure fn last<copy T>(v: [const T]) -> option::t<T> {
pure fn last<T: copy>(v: [const T]) -> option::t<T> {
if len(v) == 0u { ret none; }
ret some(v[len(v) - 1u]);
}
@ -234,7 +234,7 @@ Returns the last element of a non-empty vector `v`
Predicates:
<is_not_empty> (v)
*/
pure fn last_total<copy T>(v: [const T]) : is_not_empty(v) -> T {
pure fn last_total<T: copy>(v: [const T]) : is_not_empty(v) -> T {
ret v[len(v) - 1u];
}
@ -243,7 +243,7 @@ Function: slice
Returns a copy of the elements from [`start`..`end`) from `v`.
*/
fn slice<copy T>(v: [const T], start: uint, end: uint) -> [T] {
fn slice<T: copy>(v: [const T], start: uint, end: uint) -> [T] {
assert (start <= end);
assert (end <= len(v));
let result = [];
@ -259,7 +259,7 @@ Function: slice_mut
Returns a copy of the elements from [`start`..`end`) from `v`.
*/
fn slice_mut<copy T>(v: [const T], start: uint, end: uint) -> [mutable T] {
fn slice_mut<T: copy>(v: [const T], start: uint, end: uint) -> [mutable T] {
assert (start <= end);
assert (end <= len(v));
let result = [mutable];
@ -277,7 +277,7 @@ Function: shift
Removes the first element from a vector and return it
*/
fn shift<copy T>(&v: [const T]) -> T {
fn shift<T: copy>(&v: [const T]) -> T {
let ln = len::<T>(v);
assert (ln > 0u);
let e = v[0];
@ -291,7 +291,7 @@ Function: pop
Remove the last element from a vector and return it
*/
fn pop<copy T>(&v: [const T]) -> T {
fn pop<T: copy>(&v: [const T]) -> T {
let ln = len(v);
assert (ln > 0u);
ln -= 1u;
@ -305,7 +305,7 @@ Function: push
Append an element to a vector and return it
*/
fn push<copy T>(&v: [T], initval: T) {
fn push<T: copy>(&v: [T], initval: T) {
grow(v, 1u, initval)
}
@ -325,7 +325,7 @@ v - The vector to grow
n - The number of elements to add
initval - The value for the new elements
*/
fn grow<copy T>(&v: [T], n: uint, initval: T) {
fn grow<T: copy>(&v: [T], n: uint, initval: T) {
reserve(v, next_power_of_two(len(v) + n));
let i: uint = 0u;
while i < n { v += [initval]; i += 1u; }
@ -344,7 +344,7 @@ v - The vector to grow
n - The number of elements to add
initval - The value for the new elements
*/
fn grow_mut<copy T>(&v: [mutable T], n: uint, initval: T) {
fn grow_mut<T: copy>(&v: [mutable T], n: uint, initval: T) {
reserve(v, next_power_of_two(len(v) + n));
let i: uint = 0u;
while i < n { v += [mutable initval]; i += 1u; }
@ -380,7 +380,7 @@ 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
intervening space.
*/
fn grow_set<copy T>(&v: [mutable T], index: uint, initval: T, val: T) {
fn grow_set<T: copy>(&v: [mutable T], index: uint, initval: T, val: T) {
if index >= len(v) { grow_mut(v, index - len(v) + 1u, initval); }
v[index] = val;
}
@ -405,7 +405,7 @@ Function: map_mut
Apply a function to each element of a mutable vector and return the results
*/
fn map_mut<copy T, U>(v: [const T], f: block(T) -> U) -> [U] {
fn map_mut<T: copy, U>(v: [const T], f: block(T) -> U) -> [U] {
let result = [];
reserve(result, len(v));
for elem: T in v {
@ -420,7 +420,7 @@ Function: map2
Apply a function to each pair of elements and return the results
*/
fn map2<copy T, copy U, V>(v0: [T], v1: [U], f: block(T, U) -> V) -> [V] {
fn map2<T: copy, U: copy, V>(v0: [T], v1: [U], f: block(T, U) -> V) -> [V] {
let v0_len = len(v0);
if v0_len != len(v1) { fail; }
let u: [V] = [];
@ -437,7 +437,7 @@ Apply a function to each element of a vector and return the results
If function `f` returns `none` then that element is excluded from
the resulting vector.
*/
fn filter_map<copy T, copy U>(v: [const T], f: block(T) -> option::t<U>)
fn filter_map<T: copy, U: copy>(v: [const T], f: block(T) -> option::t<U>)
-> [U] {
let result = [];
for elem: T in v {
@ -458,7 +458,7 @@ holds.
Apply function `f` to each element of `v` and return a vector containing
only those elements for which `f` returned true.
*/
fn filter<copy T>(v: [T], f: block(T) -> bool) -> [T] {
fn filter<T: copy>(v: [T], f: block(T) -> bool) -> [T] {
let result = [];
for elem: T in v {
if f(elem) { result += [elem]; }
@ -472,7 +472,7 @@ Function: concat
Concatenate a vector of vectors. Flattens a vector of vectors of T into
a single vector of T.
*/
fn concat<copy T>(v: [const [const T]]) -> [T] {
fn concat<T: copy>(v: [const [const T]]) -> [T] {
let new: [T] = [];
for inner: [T] in v { new += inner; }
ret new;
@ -483,7 +483,7 @@ Function: foldl
Reduce a vector from left to right
*/
fn foldl<copy T, U>(z: T, v: [const U], p: block(T, U) -> T) -> T {
fn foldl<T: copy, U>(z: T, v: [const U], p: block(T, U) -> T) -> T {
let accum = z;
iter(v) { |elt|
accum = p(accum, elt);
@ -496,7 +496,7 @@ Function: foldr
Reduce a vector from right to left
*/
fn foldr<T, copy U>(v: [const T], z: U, p: block(T, U) -> U) -> U {
fn foldr<T, U: copy>(v: [const T], z: U, p: block(T, U) -> U) -> U {
let accum = z;
riter(v) { |elt|
accum = p(elt, accum);
@ -591,7 +591,7 @@ Apply function `f` to each element of `v`, starting from the first.
When function `f` returns true then an option containing the element
is returned. If `f` matches no elements then none is returned.
*/
fn find<copy T>(v: [T], f: block(T) -> bool) -> option::t<T> {
fn find<T: copy>(v: [T], f: block(T) -> bool) -> option::t<T> {
for elt: T in v { if f(elt) { ret some(elt); } }
ret none;
}
@ -637,7 +637,7 @@ vector contains the first element of the i-th tuple of the input vector,
and the i-th element of the second vector contains the second element
of the i-th tuple of the input vector.
*/
fn unzip<copy T, copy U>(v: [(T, U)]) -> ([T], [U]) {
fn unzip<T: copy, U: copy>(v: [(T, U)]) -> ([T], [U]) {
let as = [], bs = [];
for (a, b) in v { as += [a]; bs += [b]; }
ret (as, bs);
@ -655,7 +655,7 @@ Preconditions:
<same_length> (v, u)
*/
fn zip<copy T, copy U>(v: [T], u: [U]) : same_length(v, u) -> [(T, U)] {
fn zip<T: copy, U: copy>(v: [T], u: [U]) : same_length(v, u) -> [(T, U)] {
let zipped = [];
let sz = len(v), i = 0u;
assert (sz == len(u));
@ -694,7 +694,7 @@ Function: reversed
Returns a vector with the order of elements reversed
*/
fn reversed<copy T>(v: [const T]) -> [T] {
fn reversed<T: copy>(v: [const T]) -> [T] {
let rs: [T] = [];
let i = len::<T>(v);
if i == 0u { ret rs; } else { i -= 1u; }
@ -805,7 +805,7 @@ is sorted then the permutations are lexicographically sorted).
The total number of permutations produced is `len(v)!`. If `v` contains
repeated elements, then some permutations are repeated.
*/
fn permute<copy T>(v: [const T], put: block([T])) {
fn permute<T: copy>(v: [const T], put: block([T])) {
let ln = len(v);
if ln == 0u {
put([]);

View File

@ -108,7 +108,7 @@ Failure:
If `ofs` is greater or equal to the length of the vector
*/
fn get<copy T>(t: t<T>, ofs: uint) -> T {
fn get<T: copy>(t: t<T>, ofs: uint) -> T {
assert ofs < (*t).size;
ret unsafe { *ptr::mut_offset((*t).base, ofs) };
}
@ -122,7 +122,7 @@ Failure:
If `ofs` is greater or equal to the length of the vector
*/
fn set<copy T>(t: t<T>, ofs: uint, v: T) {
fn set<T: copy>(t: t<T>, ofs: uint, v: T) {
assert ofs < (*t).size;
unsafe { *ptr::mut_offset((*t).base, ofs) = v };
}

View File

@ -41,7 +41,7 @@ native mod rustrt {
type void;
type rust_port;
fn chan_id_send<send T>(t: *sys::type_desc,
fn chan_id_send<T: send>(t: *sys::type_desc,
target_task: task::task, target_port: port_id,
data: T) -> ctypes::uintptr_t;
@ -57,7 +57,7 @@ native mod rustrt {
#[abi = "rust-intrinsic"]
native mod rusti {
fn call_with_retptr<send T>(&&f: fn@(*uint)) -> T;
fn call_with_retptr<T: send>(&&f: fn@(*uint)) -> T;
}
type port_id = int;
@ -80,11 +80,11 @@ dropped.
Channels may be duplicated and themselves transmitted over other channels.
*/
tag chan<send T> {
tag chan<T: send> {
chan_t(task::task, port_id);
}
resource port_ptr<send T>(po: *rustrt::rust_port) {
resource port_ptr<T: send>(po: *rustrt::rust_port) {
// Once the port is detached it's guaranteed not to receive further
// messages
rustrt::rust_port_detach(po);
@ -108,7 +108,7 @@ transmitted. If a port value is copied, both copies refer to the same port.
Ports may be associated with multiple <chan>s.
*/
tag port<send T> { port_t(@port_ptr<T>); }
tag port<T: send> { port_t(@port_ptr<T>); }
/*
Function: send
@ -118,7 +118,7 @@ Sends data over a channel.
The sent data is moved into the channel, whereupon the caller loses access
to it.
*/
fn send<send T>(ch: chan<T>, -data: T) {
fn send<T: send>(ch: chan<T>, -data: T) {
let chan_t(t, p) = ch;
let res = rustrt::chan_id_send(sys::get_type_desc::<T>(), t, p, data);
if res != 0u unsafe {
@ -133,7 +133,7 @@ Function: port
Constructs a port.
*/
fn port<send T>() -> port<T> {
fn port<T: send>() -> port<T> {
port_t(@port_ptr(rustrt::new_port(sys::size_of::<T>())))
}
@ -145,10 +145,10 @@ Receive from a port.
If no data is available on the port then the task will block until data
becomes available.
*/
fn recv<send T>(p: port<T>) -> T { recv_(***p) }
fn recv<T: send>(p: port<T>) -> T { recv_(***p) }
// Receive on a raw port pointer
fn recv_<send T>(p: *rustrt::rust_port) -> T {
fn recv_<T: send>(p: *rustrt::rust_port) -> T {
// FIXME: Due to issue 1185 we can't use a return pointer when
// calling C code, and since we can't create our own return
// pointer on the stack, we're going to call a little intrinsic
@ -181,6 +181,6 @@ Constructs a channel.
The channel is bound to the port used to construct it.
*/
fn chan<send T>(p: port<T>) -> chan<T> {
fn chan<T: send>(p: port<T>) -> chan<T> {
chan_t(task::get_task(), rustrt::get_port_id(***p))
}

View File

@ -33,7 +33,7 @@ Section: Functions
/*
Function: create
*/
fn create<copy T>() -> t<T> {
fn create<T: copy>() -> t<T> {
type cell<T> = option::t<T>;
let initial_capacity: uint = 32u; // 2^5
@ -41,7 +41,7 @@ fn create<copy T>() -> t<T> {
* Grow is only called on full elts, so nelts is also len(elts), unlike
* elsewhere.
*/
fn grow<copy T>(nelts: uint, lo: uint, elts: [mutable cell<T>]) ->
fn grow<T: copy>(nelts: uint, lo: uint, elts: [mutable cell<T>]) ->
[mutable cell<T>] {
assert (nelts == vec::len(elts));
let rv = [mutable];
@ -57,10 +57,10 @@ fn create<copy T>() -> t<T> {
ret rv;
}
fn get<copy T>(elts: [mutable cell<T>], i: uint) -> T {
fn get<T: copy>(elts: [mutable cell<T>], i: uint) -> T {
ret alt elts[i] { option::some(t) { t } _ { fail } };
}
obj deque<copy T>(mutable nelts: uint,
obj deque<T: copy>(mutable nelts: uint,
mutable lo: uint,
mutable hi: uint,
mutable elts: [mutable cell<T>]) {

View File

@ -50,7 +50,7 @@ Function: insert
Insert a value into the map
*/
fn insert<copy K, copy V>(m: treemap<K, V>, k: K, v: V) -> treemap<K, V> {
fn insert<K: copy, V: copy>(m: treemap<K, V>, k: K, v: V) -> treemap<K, V> {
@alt m {
@empty. { node(@k, @v, @empty, @empty) }
@node(@kk, vv, left, right) {
@ -68,7 +68,7 @@ Function: find
Find a value based on the key
*/
fn find<K, copy V>(m: treemap<K, V>, k: K) -> option<V> {
fn find<K, V: copy>(m: treemap<K, V>, k: K) -> option<V> {
alt *m {
empty. { none }
node(@kk, @v, left, right) {
@ -84,7 +84,7 @@ Function: traverse
Visit all pairs in the map in order.
*/
fn traverse<K, copy V>(m: treemap<K, V>, f: block(K, V)) {
fn traverse<K, V: copy>(m: treemap<K, V>, f: block(K, V)) {
alt *m {
empty. { }
node(@k, @v, _, _) {

View File

@ -27,7 +27,7 @@ Function: from_vec
Create a list from a vector
*/
fn from_vec<copy T>(v: [const T]) -> list<T> {
fn from_vec<T: copy>(v: [const T]) -> list<T> {
*vec::foldr(v, @nil::<T>, { |h, t| @cons(h, t) })
}
@ -46,7 +46,7 @@ ls - The list to fold
z - The initial value
f - The function to apply
*/
fn foldl<copy T, U>(ls: list<U>, z: T, f: block(T, U) -> T) -> T {
fn foldl<T: copy, U>(ls: list<U>, z: T, f: block(T, U) -> T) -> T {
let accum: T = z;
iter(ls) {|elt| accum = f(accum, elt);}
accum
@ -61,7 +61,7 @@ Apply function `f` to each element of `v`, starting from the first.
When function `f` returns true then an option containing the element
is returned. If `f` matches no elements then none is returned.
*/
fn find<copy T, copy U>(ls: list<T>, f: block(T) -> option::t<U>)
fn find<T: copy, U: copy>(ls: list<T>, f: block(T) -> option::t<U>)
-> option::t<U> {
let ls = ls;
while true {
@ -80,7 +80,7 @@ Function: has
Returns true if a list contains an element with the given value
*/
fn has<copy T>(ls: list<T>, elt: T) -> bool {
fn has<T: copy>(ls: list<T>, elt: T) -> bool {
let ls = ls;
while true {
alt ls {
@ -96,7 +96,7 @@ Function: is_empty
Returns true if the list is empty.
*/
pure fn is_empty<copy T>(ls: list<T>) -> bool {
pure fn is_empty<T: copy>(ls: list<T>) -> bool {
alt ls {
nil. { true }
_ { false }
@ -108,7 +108,7 @@ Function: is_not_empty
Returns true if the list is not empty.
*/
pure fn is_not_empty<copy T>(ls: list<T>) -> bool {
pure fn is_not_empty<T: copy>(ls: list<T>) -> bool {
ret !is_empty(ls);
}
@ -128,7 +128,7 @@ Function: tail
Returns all but the first element of a list
*/
pure fn tail<copy T>(ls: list<T>) : is_not_empty(ls) -> list<T> {
pure fn tail<T: copy>(ls: list<T>) : is_not_empty(ls) -> list<T> {
alt ls {
cons(_, tl) { ret *tl; }
nil. { fail "list empty" }
@ -140,7 +140,7 @@ Function: head
Returns the first element of a list
*/
pure fn head<copy T>(ls: list<T>) : is_not_empty(ls) -> T {
pure fn head<T: copy>(ls: list<T>) : is_not_empty(ls) -> T {
alt ls {
cons(hd, _) { ret hd; }
nil. { fail "list empty" }
@ -152,7 +152,7 @@ Function: append
Appends one list to another
*/
pure fn append<copy T>(l: list<T>, m: list<T>) -> list<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); }

View File

@ -108,32 +108,32 @@ type hashmap<K, V> = obj {
/* Section: Operations */
mod chained {
type entry<copy K, copy V> = {
type entry<K: copy, V: copy> = {
hash: uint,
key: K,
mutable value: V,
mutable next: chain<K, V>
};
tag chain<copy K, copy V> {
tag chain<K: copy, V: copy> {
present(@entry<K, V>);
absent;
}
type t<copy K, copy V> = {
type t<K: copy, V: copy> = {
mutable size: uint,
mutable chains: [mutable chain<K,V>],
hasher: hashfn<K>,
eqer: eqfn<K>
};
tag search_result<copy K, copy V> {
tag search_result<K: copy, V: copy> {
not_found;
found_first(uint, @entry<K,V>);
found_after(@entry<K,V>, @entry<K,V>);
}
fn search_rem<copy K, copy V>(tbl: t<K,V>,
fn search_rem<K: copy, V: copy>(tbl: t<K,V>,
k: K,
h: uint,
idx: uint,
@ -163,7 +163,7 @@ mod chained {
util::unreachable();
}
fn search_tbl<copy K, copy V>(
fn search_tbl<K: copy, V: copy>(
tbl: t<K,V>, k: K, h: uint) -> search_result<K,V> {
let idx = h % vec::len(tbl.chains);
alt tbl.chains[idx] {
@ -185,7 +185,7 @@ mod chained {
}
}
fn insert<copy K, copy V>(tbl: t<K,V>, k: K, v: V) -> bool {
fn insert<K: copy, V: copy>(tbl: t<K,V>, k: K, v: V) -> bool {
let hash = tbl.hasher(k);
alt search_tbl(tbl, k, hash) {
not_found. {
@ -210,7 +210,7 @@ mod chained {
}
}
fn get<copy K, copy V>(tbl: t<K,V>, k: K) -> core::option::t<V> {
fn get<K: copy, V: copy>(tbl: t<K,V>, k: K) -> core::option::t<V> {
alt search_tbl(tbl, k, tbl.hasher(k)) {
not_found. {
ret core::option::none;
@ -226,7 +226,7 @@ mod chained {
}
}
fn remove<copy K, copy V>(tbl: t<K,V>, k: K) -> core::option::t<V> {
fn remove<K: copy, V: copy>(tbl: t<K,V>, k: K) -> core::option::t<V> {
alt search_tbl(tbl, k, tbl.hasher(k)) {
not_found. {
ret core::option::none;
@ -246,11 +246,11 @@ mod chained {
}
}
fn chains<copy K, copy V>(nchains: uint) -> [mutable chain<K,V>] {
fn chains<K: copy, V: copy>(nchains: uint) -> [mutable chain<K,V>] {
ret vec::init_elt_mut(absent, nchains);
}
fn foreach_entry<copy K, copy V>(chain0: chain<K,V>,
fn foreach_entry<K: copy, V: copy>(chain0: chain<K,V>,
blk: block(@entry<K,V>)) {
let chain = chain0;
while true {
@ -265,7 +265,7 @@ mod chained {
}
}
fn foreach_chain<copy K, copy V>(chains: [const chain<K,V>],
fn foreach_chain<K: copy, V: copy>(chains: [const chain<K,V>],
blk: block(@entry<K,V>)) {
let i = 0u, n = vec::len(chains);
while i < n {
@ -274,7 +274,7 @@ mod chained {
}
}
fn rehash<copy K, copy V>(tbl: t<K,V>) {
fn rehash<K: copy, V: copy>(tbl: t<K,V>) {
let old_chains = tbl.chains;
let n_old_chains = vec::len(old_chains);
let n_new_chains: uint = uint::next_power_of_two(n_old_chains + 1u);
@ -286,7 +286,7 @@ mod chained {
}
}
fn items<copy K, copy V>(tbl: t<K,V>, blk: block(K,V)) {
fn items<K: copy, V: copy>(tbl: t<K,V>, blk: block(K,V)) {
let tbl_chains = tbl.chains; // Satisfy alias checker.
foreach_chain(tbl_chains) { |entry|
let key = entry.key;
@ -295,7 +295,7 @@ mod chained {
}
}
obj o<copy K, copy V>(tbl: @t<K,V>,
obj o<K: copy, V: copy>(tbl: @t<K,V>,
lf: util::rational) {
fn size() -> uint {
ret tbl.size;
@ -343,7 +343,8 @@ mod chained {
}
}
fn mk<copy K, copy V>(hasher: hashfn<K>, eqer: eqfn<K>) -> hashmap<K,V> {
fn mk<K: copy, V: copy>(hasher: hashfn<K>, eqer: eqfn<K>)
-> hashmap<K,V> {
let initial_capacity: uint = 32u; // 2^5
let t = @{mutable size: 0u,
mutable chains: chains(initial_capacity),
@ -363,7 +364,7 @@ Parameters:
hasher - The hash function for key type K
eqer - The equality function for key type K
*/
fn mk_hashmap<copy K, copy V>(hasher: hashfn<K>, eqer: eqfn<K>)
fn mk_hashmap<K: copy, V: copy>(hasher: hashfn<K>, eqer: eqfn<K>)
-> hashmap<K, V> {
ret chained::mk(hasher, eqer);
}
@ -373,7 +374,7 @@ Function: new_str_hash
Construct a hashmap for string keys
*/
fn new_str_hash<copy V>() -> hashmap<str, V> {
fn new_str_hash<V: copy>() -> hashmap<str, V> {
ret mk_hashmap(str::hash, str::eq);
}
@ -382,7 +383,7 @@ Function: new_int_hash
Construct a hashmap for int keys
*/
fn new_int_hash<copy V>() -> hashmap<int, V> {
fn new_int_hash<V: copy>() -> hashmap<int, V> {
fn hash_int(&&x: int) -> uint { ret x as uint; }
fn eq_int(&&a: int, &&b: int) -> bool { ret a == b; }
ret mk_hashmap(hash_int, eq_int);
@ -393,7 +394,7 @@ Function: new_uint_hash
Construct a hashmap for uint keys
*/
fn new_uint_hash<copy V>() -> hashmap<uint, V> {
fn new_uint_hash<V: copy>() -> hashmap<uint, V> {
fn hash_uint(&&x: uint) -> uint { ret x; }
fn eq_uint(&&a: uint, &&b: uint) -> bool { ret a == b; }
ret mk_hashmap(hash_uint, eq_uint);

View File

@ -30,7 +30,7 @@ Function: insert
Add a value to the map. If the map already contains a value for
the specified key then the original value is replaced.
*/
fn insert<copy T>(m: smallintmap<T>, key: uint, val: T) {
fn insert<T: copy>(m: smallintmap<T>, key: uint, val: T) {
vec::grow_set::<option::t<T>>(m.v, key, none::<T>, some::<T>(val));
}
@ -40,7 +40,7 @@ Function: find
Get the value for the specified key. If the key does not exist
in the map then returns none.
*/
fn find<copy T>(m: smallintmap<T>, key: uint) -> option::t<T> {
fn find<T: copy>(m: smallintmap<T>, key: uint) -> option::t<T> {
if key < vec::len::<option::t<T>>(m.v) { ret m.v[key]; }
ret none::<T>;
}
@ -54,7 +54,7 @@ Failure:
If the key does not exist in the map
*/
fn get<copy T>(m: smallintmap<T>, key: uint) -> T {
fn get<T: copy>(m: smallintmap<T>, key: uint) -> T {
alt find(m, key) {
none. { #error("smallintmap::get(): key not present"); fail; }
some(v) { ret v; }
@ -66,13 +66,13 @@ Method: contains_key
Returns true if the map contains a value for the specified key
*/
fn contains_key<copy T>(m: smallintmap<T>, key: uint) -> bool {
fn contains_key<T: copy>(m: smallintmap<T>, key: uint) -> bool {
ret !option::is_none(find::<T>(m, key));
}
// FIXME: Are these really useful?
fn truncate<copy T>(m: smallintmap<T>, len: uint) {
fn truncate<T: copy>(m: smallintmap<T>, len: uint) {
m.v = vec::slice_mut::<option::t<T>>(m.v, 0u, len);
}

View File

@ -20,8 +20,8 @@ Merge sort. Returns a new vector containing the sorted list.
Has worst case O(n log n) performance, best case O(n), but
is not space efficient. This is a stable sort.
*/
fn merge_sort<copy T>(le: lteq<T>, v: [const T]) -> [T] {
fn merge<copy T>(le: lteq<T>, a: [T], b: [T]) -> [T] {
fn merge_sort<T: copy>(le: lteq<T>, v: [const T]) -> [T] {
fn merge<T: copy>(le: lteq<T>, a: [T], b: [T]) -> [T] {
let rs: [T] = [];
let a_len: uint = len::<T>(a);
let a_ix: uint = 0u;
@ -46,7 +46,7 @@ fn merge_sort<copy T>(le: lteq<T>, v: [const T]) -> [T] {
ret merge::<T>(le, merge_sort::<T>(le, a), merge_sort::<T>(le, b));
}
fn part<copy T>(compare_func: lteq<T>, arr: [mutable T], left: uint,
fn part<T: copy>(compare_func: lteq<T>, arr: [mutable T], left: uint,
right: uint, pivot: uint) -> uint {
let pivot_value = arr[pivot];
arr[pivot] <-> arr[right];
@ -63,7 +63,7 @@ fn part<copy T>(compare_func: lteq<T>, arr: [mutable T], left: uint,
ret storage_index;
}
fn qsort<copy T>(compare_func: lteq<T>, arr: [mutable T], left: uint,
fn qsort<T: copy>(compare_func: lteq<T>, arr: [mutable T], left: uint,
right: uint) {
if right > left {
let pivot = (left + right) / 2u;
@ -84,12 +84,12 @@ Quicksort. Sorts a mutable vector in place.
Has worst case O(n^2) performance, average case O(n log n).
This is an unstable sort.
*/
fn quick_sort<copy T>(compare_func: lteq<T>, arr: [mutable T]) {
fn quick_sort<T: copy>(compare_func: lteq<T>, arr: [mutable T]) {
if len::<T>(arr) == 0u { ret; }
qsort::<T>(compare_func, arr, 0u, len::<T>(arr) - 1u);
}
fn qsort3<copy T>(compare_func_lt: lteq<T>, compare_func_eq: lteq<T>,
fn qsort3<T: copy>(compare_func_lt: lteq<T>, compare_func_eq: lteq<T>,
arr: [mutable T], left: int, right: int) {
if right <= left { ret; }
let v: T = arr[right];
@ -150,7 +150,7 @@ According to these slides this is the algorithm of choice for
This is an unstable sort.
*/
fn quick_sort3<copy T>(compare_func_lt: lteq<T>, compare_func_eq: lteq<T>,
fn quick_sort3<T: copy>(compare_func_lt: lteq<T>, compare_func_eq: lteq<T>,
arr: [mutable T]) {
if len::<T>(arr) == 0u { ret; }
qsort3::<T>(compare_func_lt, compare_func_eq, arr, 0,

View File

@ -115,7 +115,7 @@ fn run_tests_console(opts: test_opts,
run_tests_console_(opts, tests, default_test_to_task)
}
fn run_tests_console_<copy T>(opts: test_opts, tests: [test_desc<T>],
fn run_tests_console_<T: copy>(opts: test_opts, tests: [test_desc<T>],
to_task: test_to_task<T>) -> bool {
type test_state =
@ -127,7 +127,7 @@ fn run_tests_console_<copy T>(opts: test_opts, tests: [test_desc<T>],
mutable ignored: uint,
mutable failures: [test_desc<T>]};
fn callback<copy T>(event: testevent<T>, st: test_state) {
fn callback<T: copy>(event: testevent<T>, st: test_state) {
alt event {
te_filtered(filtered_tests) {
st.total = vec::len(filtered_tests);
@ -220,7 +220,7 @@ tag testevent<T> {
te_result(test_desc<T>, test_result);
}
fn run_tests<copy T>(opts: test_opts, tests: [test_desc<T>],
fn run_tests<T: copy>(opts: test_opts, tests: [test_desc<T>],
to_task: test_to_task<T>,
callback: fn@(testevent<T>)) {
@ -254,7 +254,7 @@ fn run_tests<copy T>(opts: test_opts, tests: [test_desc<T>],
fn get_concurrency() -> uint { rustrt::sched_threads() }
fn filter_tests<copy T>(opts: test_opts,
fn filter_tests<T: copy>(opts: test_opts,
tests: [test_desc<T>]) -> [test_desc<T>] {
let filtered = tests;
@ -268,7 +268,7 @@ fn filter_tests<copy T>(opts: test_opts,
option::none. { "" }
};
fn filter_fn<copy T>(test: test_desc<T>, filter_str: str) ->
fn filter_fn<T: copy>(test: test_desc<T>, filter_str: str) ->
option::t<test_desc<T>> {
if str::find(test.name, filter_str) >= 0 {
ret option::some(test);
@ -284,7 +284,7 @@ fn filter_tests<copy T>(opts: test_opts,
filtered = if !opts.run_ignored {
filtered
} else {
fn filter<copy T>(test: test_desc<T>) -> option::t<test_desc<T>> {
fn filter<T: copy>(test: test_desc<T>) -> option::t<test_desc<T>> {
if test.ignore {
ret option::some({name: test.name,
fn: test.fn,
@ -310,7 +310,7 @@ fn filter_tests<copy T>(opts: test_opts,
type test_future<T> = {test: test_desc<T>, wait: fn@() -> test_result};
fn run_test<copy T>(test: test_desc<T>,
fn run_test<T: copy>(test: test_desc<T>,
to_task: test_to_task<T>) -> test_future<T> {
if test.ignore {
ret {test: test, wait: fn () -> test_result { tr_ignored }};

View File

@ -44,7 +44,7 @@ Function: insert
Insert a value into the map
*/
fn insert<copy K, copy V>(m: treemap<K, V>, k: K, v: V) {
fn insert<K: copy, V: copy>(m: treemap<K, V>, k: K, v: V) {
alt m {
@empty. { *m = node(@k, @v, @mutable empty, @mutable empty); }
@node(@kk, _, _, _) {
@ -63,7 +63,7 @@ Function: find
Find a value based on the key
*/
fn find<copy K, copy V>(m: treemap<K, V>, k: K) -> option<V> {
fn find<K: copy, V: copy>(m: treemap<K, V>, k: K) -> option<V> {
alt *m {
empty. { none }
node(@kk, @v, _, _) {

View File

@ -7,7 +7,7 @@ Function: id
The identity function
*/
pure fn id<copy T>(x: T) -> T { x }
pure fn id<T: copy>(x: T) -> T { x }
/*
Function: unreachable

View File

@ -55,25 +55,25 @@ mod map_reduce {
export reducer;
export map_reduce;
type putter<send K, send V> = fn(K, V);
type putter<K: send, V: send> = fn(K, V);
// FIXME: the first K1 parameter should probably be a -, but that
// doesn't parse at the moment.
type mapper<send K1, send K2, send V> = fn(K1, putter<K2, V>);
type mapper<K1: send, K2: send, V: send> = fn(K1, putter<K2, V>);
type getter<send V> = fn() -> option<V>;
type getter<V: send> = fn() -> option<V>;
type reducer<send K, send V> = fn(K, getter<V>);
type reducer<K: send, V: send> = fn(K, getter<V>);
tag ctrl_proto<send K, send V> {
tag ctrl_proto<K: send, V: send> {
find_reducer(K, chan<chan<reduce_proto<V>>>);
mapper_done;
}
tag reduce_proto<send V> { emit_val(V); done; ref; release; }
tag reduce_proto<V: send> { emit_val(V); done; ref; release; }
fn start_mappers<send K1, send K2,
send V>(map: mapper<K1, K2, V>,
fn start_mappers<K1: send, K2: send,
V: send>(map: mapper<K1, K2, V>,
ctrl: chan<ctrl_proto<K2, V>>, inputs: [K1]) ->
[joinable_task] {
let tasks = [];
@ -84,15 +84,15 @@ mod map_reduce {
ret tasks;
}
fn map_task<send K1, send K2,
send V>(-map: mapper<K1, K2, V>,
fn map_task<K: send1, K: send2,
V: send>(-map: mapper<K1, K2, V>,
-ctrl: chan<ctrl_proto<K2, V>>,
-input: K1) {
// log(error, "map_task " + input);
let intermediates = treemap::init();
fn emit<send K2,
send V>(im: treemap::treemap<K2, chan<reduce_proto<V>>>,
fn emit<K: send2,
V: send>(im: treemap::treemap<K2, chan<reduce_proto<V>>>,
ctrl: chan<ctrl_proto<K2, V>>, key: K2, val: V) {
let c;
alt treemap::find(im, key) {
@ -110,15 +110,15 @@ mod map_reduce {
map(input, bind emit(intermediates, ctrl, _, _));
fn finish<send K, send V>(_k: K, v: chan<reduce_proto<V>>) {
fn finish<K: send, V: send>(_k: K, v: chan<reduce_proto<V>>) {
send(v, release);
}
treemap::traverse(intermediates, finish);
send(ctrl, mapper_done);
}
fn reduce_task<send K,
send V>(-reduce: reducer<K, V>, -key: K,
fn reduce_task<K: send,
V: send>(-reduce: reducer<K, V>, -key: K,
-out: chan<chan<reduce_proto<V>>>) {
let p = port();
@ -127,7 +127,7 @@ mod map_reduce {
let ref_count = 0;
let is_done = false;
fn get<send V>(p: port<reduce_proto<V>>,
fn get<V: send>(p: port<reduce_proto<V>>,
&ref_count: int, &is_done: bool)
-> option<V> {
while !is_done || ref_count > 0 {
@ -150,8 +150,8 @@ mod map_reduce {
reduce(key, bind get(p, ref_count, is_done));
}
fn map_reduce<send K1, send K2,
send V>(map: mapper<K1, K2, V>, reduce: reducer<K2, V>,
fn map_reduce<K: send1, K: send2,
V: send>(map: mapper<K1, K2, V>, reduce: reducer<K2, V>,
inputs: [K1]) {
let ctrl = port();
@ -195,7 +195,7 @@ mod map_reduce {
}
}
fn finish<send K, send V>(_k: K, v: chan<reduce_proto<V>>) {
fn finish<K: send, V: send>(_k: K, v: chan<reduce_proto<V>>) {
send(v, done);
}
treemap::traverse(reducers, finish);

View File

@ -1,6 +1,6 @@
// error-pattern: instantiating a sendable type parameter with a copyable type
fn f<send T>(i: T) {
fn f<T: send>(i: T) {
}
fn main() {

View File

@ -1,5 +1,5 @@
// error-pattern: Unsatisfied precondition constraint
fn send<send T>(ch: _chan<T>, -data: T) {
fn send<T: send>(ch: _chan<T>, -data: T) {
log(debug, ch);
log(debug, data);
fail;

View File

@ -4,8 +4,8 @@ fn test00_start(ch: chan_t<int>, message: int) { send(ch, copy message); }
type task_id = int;
type port_id = int;
type chan_t<send T> = {task: task_id, port: port_id};
type chan_t<T: send> = {task: task_id, port: port_id};
fn send<send T>(ch: chan_t<T>, -data: T) { fail; }
fn send<T: send>(ch: chan_t<T>, -data: T) { fail; }
fn main() { fail "quux"; }

View File

@ -5,7 +5,7 @@ import comm::port;
import comm::send;
import comm::recv;
fn echo<send T>(c: chan<T>, oc: chan<chan<T>>) {
fn echo<T: send>(c: chan<T>, oc: chan<chan<T>>) {
// Tests that the type argument in port gets
// visited
let p = port::<T>();

View File

@ -2,7 +2,7 @@
// -*- rust -*-
fn f<copy T, copy U>(x: T, y: U) -> {a: T, b: U} { ret {a: x, b: y}; }
fn f<T: copy, U: copy>(x: T, y: U) -> {a: T, b: U} { ret {a: x, b: y}; }
fn main() {
log(debug, f({x: 3, y: 4, z: 5}, 4).a.x);

View File

@ -1,4 +1,4 @@
fn wrapper3<copy T>(i: T, j: int) {
fn wrapper3<T: copy>(i: T, j: int) {
log(debug, i);
log(debug, j);
// This is a regression test that the spawn3 thunk to wrapper3
@ -6,7 +6,7 @@ fn wrapper3<copy T>(i: T, j: int) {
assert j == 123456789;
}
fn spawn3<copy T>(i: T, j: int) {
fn spawn3<T: copy>(i: T, j: int) {
let wrapped = bind wrapper3(i, j);
wrapped();
}

View File

@ -1,8 +1,8 @@
type box<copy T> = {c: @T};
type box<T: copy> = {c: @T};
fn unbox<copy T>(b: box<T>) -> T { ret *b.c; }
fn unbox<T: copy>(b: box<T>) -> T { ret *b.c; }
fn main() {
let foo: int = 17;

View File

@ -4,7 +4,7 @@
// -*- rust -*-
type compare<T> = fn@(T, T) -> bool;
fn test_generic<copy T>(expected: T, eq: compare<T>) {
fn test_generic<T: copy>(expected: T, eq: compare<T>) {
let actual: T = alt true { true { expected } };
assert (eq(expected, actual));
}

View File

@ -3,7 +3,7 @@
// -*- rust -*-
type compare<T> = fn@(~T, ~T) -> bool;
fn test_generic<copy T>(expected: ~T, eq: compare<T>) {
fn test_generic<T: copy>(expected: ~T, eq: compare<T>) {
let actual: ~T = alt true { true { expected } };
assert (eq(expected, actual));
}

View File

@ -4,7 +4,7 @@
// -*- rust -*-
type compare<T> = fn@(T, T) -> bool;
fn test_generic<copy T>(expected: T, eq: compare<T>) {
fn test_generic<T: copy>(expected: T, eq: compare<T>) {
let actual: T = alt true { true { expected } };
assert (eq(expected, actual));
}

View File

@ -4,7 +4,7 @@
// -*- rust -*-
type compare<T> = fn@(T, T) -> bool;
fn test_generic<copy T>(expected: T, eq: compare<T>) {
fn test_generic<T: copy>(expected: T, eq: compare<T>) {
let actual: T = alt true { true { expected } };
assert (eq(expected, actual));
}

View File

@ -4,7 +4,7 @@
// -*- rust -*-
type compare<T> = fn@(T, T) -> bool;
fn test_generic<copy T>(expected: T, eq: compare<T>) {
fn test_generic<T: copy>(expected: T, eq: compare<T>) {
let actual: T = { expected };
assert (eq(expected, actual));
}

View File

@ -3,7 +3,7 @@
// -*- rust -*-
type compare<T> = fn@(~T, ~T) -> bool;
fn test_generic<copy T>(expected: ~T, eq: compare<T>) {
fn test_generic<T: copy>(expected: ~T, eq: compare<T>) {
let actual: ~T = { expected };
assert (eq(expected, actual));
}

View File

@ -4,7 +4,7 @@
// -*- rust -*-
type compare<T> = fn@(T, T) -> bool;
fn test_generic<copy T>(expected: T, eq: compare<T>) {
fn test_generic<T: copy>(expected: T, eq: compare<T>) {
let actual: T = { expected };
assert (eq(expected, actual));
}

View File

@ -6,7 +6,7 @@
// Tests for standalone blocks as expressions with dynamic type sizes
type compare<T> = fn@(T, T) -> bool;
fn test_generic<copy T>(expected: T, eq: compare<T>) {
fn test_generic<T: copy>(expected: T, eq: compare<T>) {
let actual: T = { expected };
assert (eq(expected, actual));
}

View File

@ -9,7 +9,7 @@ fn test_vec() {
}
fn test_generic() {
fn f<copy T>(t: T) -> T { t }
fn f<T: copy>(t: T) -> T { t }
assert (f(10) == 10);
}

View File

@ -4,7 +4,7 @@
// -*- rust -*-
type compare<T> = fn@(T, T) -> bool;
fn test_generic<copy T>(expected: T, not_expected: T, eq: compare<T>) {
fn test_generic<T: copy>(expected: T, not_expected: T, eq: compare<T>) {
let actual: T = if true { expected } else { not_expected };
assert (eq(expected, actual));
}

View File

@ -6,7 +6,7 @@
// Tests for if as expressions with dynamic type sizes
type compare<T> = fn@(T, T) -> bool;
fn test_generic<copy T>(expected: T, not_expected: T, eq: compare<T>) {
fn test_generic<T: copy>(expected: T, not_expected: T, eq: compare<T>) {
let actual: T = if true { expected } else { not_expected };
assert (eq(expected, actual));
}

View File

@ -1,8 +1,8 @@
fn fix_help<A, send B>(f: fn(fn@(A) -> B, A) -> B, x: A) -> B {
fn fix_help<A, B: send>(f: fn(fn@(A) -> B, A) -> B, x: A) -> B {
ret f(bind fix_help(f, _), x);
}
fn fix<A, send B>(f: fn(fn@(A) -> B, A) -> B) -> fn@(A) -> B {
fn fix<A, B: send>(f: fn(fn@(A) -> B, A) -> B) -> fn@(A) -> B {
ret bind fix_help(f, _);
}

View File

@ -1,6 +1,6 @@
// This is what the signature to spawn should look like with bare functions
fn spawn<send T>(val: T, f: fn(T)) {
fn spawn<T: send>(val: T, f: fn(T)) {
f(val);
}

View File

@ -1,5 +1,5 @@
obj ob<copy K>(k: K) {
obj ob<K: copy>(k: K) {
fn foo(it: block(~{a: K})) { it(~{a: k}); }
}

View File

@ -1,6 +1,6 @@
fn id<copy T>(t: T) -> T { ret t; }
fn id<T: copy>(t: T) -> T { ret t; }
fn main() {
let expected = @100;

View File

@ -1,6 +1,6 @@
fn id<send T>(t: T) -> T { ret t; }
fn id<T: send>(t: T) -> T { ret t; }
fn main() {
let expected = ~100;

View File

@ -1,6 +1,6 @@
fn id<copy T>(t: T) -> T { ret t; }
fn id<T: copy>(t: T) -> T { ret t; }
fn main() {
let t = {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7};

View File

@ -1,6 +1,6 @@
fn id<copy T>(t: T) -> T { ret t; }
fn id<T: copy>(t: T) -> T { ret t; }
fn main() {
let t = {_0: 1, _1: 2, _2: 3, _3: 4, _4: 5, _5: 6, _6: 7};

View File

@ -1,6 +1,6 @@
fn box<copy T>(x: {x: T, y: T, z: T}) -> @{x: T, y: T, z: T} { ret @x; }
fn box<T: copy>(x: {x: T, y: T, z: T}) -> @{x: T, y: T, z: T} { ret @x; }
fn main() {
let x: @{x: int, y: int, z: int} = box::<int>({x: 1, y: 2, z: 3});

View File

@ -1,8 +1,8 @@
fn g<copy X>(x: X) -> X { ret x; }
fn g<X: copy>(x: X) -> X { ret x; }
fn f<copy T>(t: T) -> {a: T, b: T} {
fn f<T: copy>(t: T) -> {a: T, b: T} {
type pair = {a: T, b: T};
let x: pair = {a: t, b: t};

View File

@ -1,5 +1,5 @@
fn f<copy T>(t: T) { let t1: T = t; }
fn f<T: copy>(t: T) { let t1: T = t; }
fn main() { let x = {x: @10, y: @12}; f(x); }

View File

@ -1,8 +1,8 @@
type recbox<copy T> = {x: @T};
type recbox<T: copy> = {x: @T};
fn reclift<copy T>(t: T) -> recbox<T> { ret {x: @t}; }
fn reclift<T: copy>(t: T) -> recbox<T> { ret {x: @t}; }
fn main() {
let foo: int = 17;

View File

@ -1,6 +1,6 @@
type recbox<copy T> = {x: ~T};
type recbox<T: copy> = {x: ~T};
fn reclift<copy T>(t: T) -> recbox<T> { ret {x: ~t}; }
fn reclift<T: copy>(t: T) -> recbox<T> { ret {x: ~t}; }
fn main() {
let foo: int = 17;

View File

@ -4,6 +4,6 @@
// -*- rust -*-
// Issue #45: infer type parameters in function applications
fn id<copy T>(x: T) -> T { ret x; }
fn id<T: copy>(x: T) -> T { ret x; }
fn main() { let x: int = 42; let y: int = id(x); assert (x == y); }

View File

@ -1,4 +1,4 @@
fn f<copy T>(x: ~T) -> ~T { ret x; }
fn f<T: copy>(x: ~T) -> ~T { ret x; }
fn main() { let x = f(~3); log(debug, *x); }

View File

@ -2,7 +2,7 @@
// -*- rust -*-
fn id<copy T>(x: T) -> T { ret x; }
fn id<T: copy>(x: T) -> T { ret x; }
type triple = {x: int, y: int, z: int};

View File

@ -1,6 +1,6 @@
obj handle<copy T>(data: T) {
obj handle<T: copy>(data: T) {
fn get() -> T { ret data; }
}

View File

@ -1,6 +1,6 @@
obj buf<copy T>(data: {_0: T, _1: T, _2: T}) {
obj buf<T: copy>(data: {_0: T, _1: T, _2: T}) {
fn get(i: int) -> T {
if i == 0 {
ret data._0;

View File

@ -1,4 +1,4 @@
fn get_third<copy T>(t: (T, T, T)) -> T { let (_, _, x) = t; ret x; }
fn get_third<T: copy>(t: (T, T, T)) -> T { let (_, _, x) = t; ret x; }
fn main() {
log(debug, get_third((1, 2, 3)));

View File

@ -1,5 +1,5 @@
fn box<copy T>(x: {x: T, y: T, z: T}) -> ~{x: T, y: T, z: T} { ret ~x; }
fn box<T: copy>(x: {x: T, y: T, z: T}) -> ~{x: T, y: T, z: T} { ret ~x; }
fn main() {
let x: ~{x: int, y: int, z: int} = box::<int>({x: 1, y: 2, z: 3});

View File

@ -1,5 +1,5 @@
fn quux<copy T>(x: T) -> T { let f = bind id::<T>(_); ret f(x); }
fn quux<T: copy>(x: T) -> T { let f = bind id::<T>(_); ret f(x); }
fn id<copy T>(x: T) -> T { ret x; }
fn id<T: copy>(x: T) -> T { ret x; }
fn main() { assert (quux(10) == 10); }

View File

@ -1,4 +1,4 @@
fn double<copy T>(a: T) -> [T] { ret [a] + [a]; }
fn double<T: copy>(a: T) -> [T] { ret [a] + [a]; }
fn double_int(a: int) -> [int] { ret [a] + [a]; }

View File

@ -1,8 +1,8 @@
tag myvec<X> = [X];
fn myvec_deref<copy X>(mv: myvec<X>) -> [X] { ret *mv; }
fn myvec_deref<X: copy>(mv: myvec<X>) -> [X] { ret *mv; }
fn myvec_elt<copy X>(mv: myvec<X>) -> X { ret mv[0]; }
fn myvec_elt<X: copy>(mv: myvec<X>) -> X { ret mv[0]; }
fn main() {
let mv = myvec([1, 2, 3]);

View File

@ -2,19 +2,19 @@ use std;
import std::list::*;
pure fn pure_length_go<copy T>(ls: list<T>, acc: uint) -> uint {
pure fn pure_length_go<T: copy>(ls: list<T>, acc: uint) -> uint {
alt ls { nil. { acc } cons(_, tl) { pure_length_go(*tl, acc + 1u) } }
}
pure fn pure_length<copy T>(ls: list<T>) -> uint { pure_length_go(ls, 0u) }
pure fn pure_length<T: copy>(ls: list<T>) -> uint { pure_length_go(ls, 0u) }
pure fn nonempty_list<copy T>(ls: list<T>) -> bool { pure_length(ls) > 0u }
pure fn nonempty_list<T: copy>(ls: list<T>) -> bool { pure_length(ls) > 0u }
// Of course, the compiler can't take advantage of the
// knowledge that ls is a cons node. Future work.
// Also, this is pretty contrived since nonempty_list
// could be a "tag refinement", if we implement those.
fn safe_head<copy T>(ls: list<T>) : nonempty_list(ls) -> T {
fn safe_head<T: copy>(ls: list<T>) : nonempty_list(ls) -> T {
check is_not_empty(ls);
ret head(ls);
}

View File

@ -6,7 +6,7 @@ tag clam<T> { signed(int); unsigned(uint); }
fn getclam<T>() -> clam<T> { ret signed::<T>(42); }
obj impatience<copy T>() {
obj impatience<T: copy>() {
fn moreclam() -> clam<T> { be getclam::<T>(); }
}

View File

@ -2,6 +2,6 @@
tag option<T> { none; some(T); }
fn f<copy T>() -> option<T> { ret none; }
fn f<T: copy>() -> option<T> { ret none; }
fn main() { f::<int>(); }

View File

@ -4,9 +4,9 @@ import comm::send;
import comm::port;
// tests that ctrl's type gets inferred properly
type command<send K, send V> = {key: K, val: V};
type command<K: send, V: send> = {key: K, val: V};
fn cache_server<send K, send V>(c: chan<chan<command<K, V>>>) {
fn cache_server<K: send, V: send>(c: chan<chan<command<K, V>>>) {
let ctrl = port();
send(c, chan(ctrl));
}

View File

@ -8,7 +8,7 @@ fn main() { test05(); }
type pair<A,B> = { a: A, b: B };
fn make_generic_record<copy A,copy B>(a: A, b: B) -> pair<A,B> {
fn make_generic_record<A: copy, B: copy>(a: A, b: B) -> pair<A,B> {
ret {a: a, b: b};
}
@ -24,7 +24,7 @@ fn test05_start(&&f: sendfn(&&float, &&str) -> pair<float, str>) {
assert q.b == "Ho";
}
fn spawn<copy A, copy B>(f: fn(sendfn(A,B)->pair<A,B>)) {
fn spawn<A: copy, B: copy>(f: fn(sendfn(A,B)->pair<A,B>)) {
let arg = sendfn(a: A, b: B) -> pair<A,B> {
ret make_generic_record(a, b);
};

View File

@ -1,6 +1,6 @@
fn p_foo<T>(pinned: T) { }
fn s_foo<copy T>(shared: T) { }
fn u_foo<send T>(unique: T) { }
fn s_foo<T: copy>(shared: T) { }
fn u_foo<T: send>(unique: T) { }
resource r(i: int) { }

View File

@ -7,7 +7,7 @@ import std::list::*;
// Can't easily be written as a "pure fn" because there's
// no syntax for specifying that f is pure.
fn pure_foldl<copy T, copy U>(ls: list<T>, u: U, f: block(T, U) -> U) -> U {
fn pure_foldl<T: copy, U: copy>(ls: list<T>, u: U, f: block(T, U) -> U) -> U {
alt ls {
nil. { u }
cons(hd, tl) { f(hd, pure_foldl(*tl, f(hd, u), f)) }
@ -16,18 +16,18 @@ fn pure_foldl<copy T, copy U>(ls: list<T>, u: U, f: block(T, U) -> U) -> U {
// Shows how to use an "unchecked" block to call a general
// fn from a pure fn
pure fn pure_length<copy T>(ls: list<T>) -> uint {
pure fn pure_length<T: copy>(ls: list<T>) -> uint {
fn count<T>(_t: T, &&u: uint) -> uint { u + 1u }
unchecked{ pure_foldl(ls, 0u, bind count(_, _)) }
}
pure fn nonempty_list<copy T>(ls: list<T>) -> bool { pure_length(ls) > 0u }
pure fn nonempty_list<T: copy>(ls: list<T>) -> bool { pure_length(ls) > 0u }
// Of course, the compiler can't take advantage of the
// knowledge that ls is a cons node. Future work.
// Also, this is pretty contrived since nonempty_list
// could be a "tag refinement", if we implement those.
fn safe_head<copy T>(ls: list<T>) : nonempty_list(ls) -> T {
fn safe_head<T: copy>(ls: list<T>) : nonempty_list(ls) -> T {
check is_not_empty(ls);
ret head(ls)
}

View File

@ -1,4 +1,4 @@
fn f<copy T>(t: T) -> T {
fn f<T: copy>(t: T) -> T {
let t1 = t;
t1
}

View File

@ -1,6 +1,6 @@
// Issue #976
fn f<copy T>(x: ~T) {
fn f<T: copy>(x: ~T) {
let _x2 = x;
}
fn main() { }

View File

@ -1,10 +1,10 @@
fn sendable() {
fn f<send T>(i: T, j: T) {
fn f<T: send>(i: T, j: T) {
assert i == j;
}
fn g<send T>(i: T, j: T) {
fn g<T: send>(i: T, j: T) {
assert i != j;
}
@ -18,11 +18,11 @@ fn sendable() {
fn copyable() {
fn f<copy T>(i: T, j: T) {
fn f<T: copy>(i: T, j: T) {
assert i == j;
}
fn g<copy T>(i: T, j: T) {
fn g<T: copy>(i: T, j: T) {
assert i != j;
}

View File

@ -1,5 +1,5 @@
fn push<copy T>(&v: [const T], t: T) { v += [t]; }
fn push<T: copy>(&v: [const T], t: T) { v += [t]; }
fn main() { let v = [1, 2, 3]; push(v, 1); }

View File

@ -81,7 +81,7 @@ fn test_boxes(a: @int, b: @int, c: @int, d: @int) {
type eqfn<T> = fn@(T, T) -> bool;
fn test_parameterized<copy T>(e: eqfn<T>, a: T, b: T, c: T, d: T) {
fn test_parameterized<T: copy>(e: eqfn<T>, a: T, b: T, c: T, d: T) {
let deq: deque::t<T> = deque::create::<T>();
assert (deq.size() == 0u);
deq.add_front(a);

View File

@ -70,7 +70,7 @@ fn test_join_convenient() {
#[ignore]
fn spawn_polymorphic() {
// FIXME #1038: Can't spawn palymorphic functions
/*fn foo<send T>(x: T) { log(error, x); }
/*fn foo<T: send>(x: T) { log(error, x); }
task::spawn(true, foo);
task::spawn(42, foo);*/