about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2012-01-05 15:35:37 +0100
committerMarijn Haverbeke <marijnh@gmail.com>2012-01-05 15:50:02 +0100
commit60ae1590af034755b5cb1e1e71f2240a710299a2 (patch)
tree605d11f071a776c0ca33dcfea0a774379b0880bb
parent1f71a0f48d18d80ff3be6970d582c5a67f976329 (diff)
downloadrust-60ae1590af034755b5cb1e1e71f2240a710299a2.tar.gz
rust-60ae1590af034755b5cb1e1e71f2240a710299a2.zip
Switch to new param kind bound syntax
And remove support for the old syntax
-rw-r--r--src/comp/driver/driver.rs2
-rw-r--r--src/comp/front/attr.rs2
-rw-r--r--src/comp/front/test.rs2
-rw-r--r--src/comp/metadata/encoder.rs2
-rw-r--r--src/comp/metadata/tydecode.rs2
-rw-r--r--src/comp/middle/ast_map.rs6
-rw-r--r--src/comp/middle/debuginfo.rs4
-rw-r--r--src/comp/middle/ty.rs2
-rw-r--r--src/comp/syntax/ast_util.rs4
-rw-r--r--src/comp/syntax/ext/simplext.rs2
-rw-r--r--src/comp/syntax/parse/parser.rs18
-rw-r--r--src/comp/syntax/util/interner.rs6
-rw-r--r--src/comp/util/common.rs2
-rw-r--r--src/comp/util/filesearch.rs2
-rw-r--r--src/fuzzer/fuzzer.rs2
-rw-r--r--src/libcore/comm.rs20
-rw-r--r--src/libcore/either.rs10
-rw-r--r--src/libcore/float.rs4
-rw-r--r--src/libcore/option.rs8
-rw-r--r--src/libcore/result.rs8
-rw-r--r--src/libcore/task.rs10
-rw-r--r--src/libcore/vec.rs58
-rw-r--r--src/libstd/c_vec.rs4
-rw-r--r--src/libstd/comm.rs20
-rw-r--r--src/libstd/deque.rs8
-rw-r--r--src/libstd/fun_treemap.rs6
-rw-r--r--src/libstd/list.rs18
-rw-r--r--src/libstd/map.rs41
-rw-r--r--src/libstd/smallintmap.rs10
-rw-r--r--src/libstd/sort.rs14
-rw-r--r--src/libstd/test.rs14
-rw-r--r--src/libstd/treemap.rs4
-rw-r--r--src/libstd/util.rs2
-rw-r--r--src/test/bench/task-perf-word-count-generic.rs38
-rw-r--r--src/test/compile-fail/unique-unique-kind.rs2
-rw-r--r--src/test/compile-fail/use-after-send.rs2
-rw-r--r--src/test/run-fail/bug-811.rs4
-rw-r--r--src/test/run-fail/port-type.rs2
-rw-r--r--src/test/run-pass/auto-instantiate.rs2
-rw-r--r--src/test/run-pass/bind-generic.rs4
-rw-r--r--src/test/run-pass/box-unbox.rs4
-rw-r--r--src/test/run-pass/expr-alt-generic-box2.rs2
-rw-r--r--src/test/run-pass/expr-alt-generic-unique1.rs2
-rw-r--r--src/test/run-pass/expr-alt-generic-unique2.rs2
-rw-r--r--src/test/run-pass/expr-alt-generic.rs2
-rw-r--r--src/test/run-pass/expr-block-generic-box2.rs2
-rw-r--r--src/test/run-pass/expr-block-generic-unique1.rs2
-rw-r--r--src/test/run-pass/expr-block-generic-unique2.rs2
-rw-r--r--src/test/run-pass/expr-block-generic.rs2
-rw-r--r--src/test/run-pass/expr-fn.rs2
-rw-r--r--src/test/run-pass/expr-if-generic-box2.rs2
-rw-r--r--src/test/run-pass/expr-if-generic.rs2
-rw-r--r--src/test/run-pass/fixed-point-bind-unique.rs4
-rw-r--r--src/test/run-pass/fn-bare-spawn.rs2
-rw-r--r--src/test/run-pass/foreach-unique-drop.rs2
-rw-r--r--src/test/run-pass/generic-alias-box.rs2
-rw-r--r--src/test/run-pass/generic-alias-unique.rs2
-rw-r--r--src/test/run-pass/generic-bind-2.rs2
-rw-r--r--src/test/run-pass/generic-bind.rs2
-rw-r--r--src/test/run-pass/generic-box.rs2
-rw-r--r--src/test/run-pass/generic-derived-type.rs4
-rw-r--r--src/test/run-pass/generic-drop-glue.rs2
-rw-r--r--src/test/run-pass/generic-exterior-box.rs4
-rw-r--r--src/test/run-pass/generic-exterior-unique.rs4
-rw-r--r--src/test/run-pass/generic-fn-infer.rs2
-rw-r--r--src/test/run-pass/generic-fn-unique.rs2
-rw-r--r--src/test/run-pass/generic-fn.rs2
-rw-r--r--src/test/run-pass/generic-obj-with-derived-type.rs2
-rw-r--r--src/test/run-pass/generic-obj.rs2
-rw-r--r--src/test/run-pass/generic-tup.rs2
-rw-r--r--src/test/run-pass/generic-unique.rs2
-rw-r--r--src/test/run-pass/issue-333.rs4
-rw-r--r--src/test/run-pass/ivec-add.rs2
-rw-r--r--src/test/run-pass/newtype-polymorphic.rs4
-rw-r--r--src/test/run-pass/non-boolean-pure-fns.rs8
-rw-r--r--src/test/run-pass/obj-return-polytypes.rs2
-rw-r--r--src/test/run-pass/ret-none.rs2
-rw-r--r--src/test/run-pass/send-type-inference.rs4
-rw-r--r--src/test/run-pass/sendfn-generic-fn.rs4
-rw-r--r--src/test/run-pass/type-param-constraints.rs4
-rw-r--r--src/test/run-pass/unchecked-predicates.rs8
-rw-r--r--src/test/run-pass/unique-assign-generic.rs2
-rw-r--r--src/test/run-pass/unique-generic-assign.rs2
-rw-r--r--src/test/run-pass/unique-kinds.rs8
-rw-r--r--src/test/run-pass/vec-push.rs2
-rw-r--r--src/test/stdtest/deque.rs2
-rw-r--r--src/test/stdtest/task.rs2
87 files changed, 251 insertions, 252 deletions
diff --git a/src/comp/driver/driver.rs b/src/comp/driver/driver.rs
index b8a6ba28729..74aafca0a15 100644
--- a/src/comp/driver/driver.rs
+++ b/src/comp/driver/driver.rs
@@ -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}};
diff --git a/src/comp/front/attr.rs b/src/comp/front/attr.rs
index 09c7ec8f12b..5ae398e238c 100644
--- a/src/comp/front/attr.rs
+++ b/src/comp/front/attr.rs
@@ -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()};
 }
 
diff --git a/src/comp/front/test.rs b/src/comp/front/test.rs
index f8aa8bdac53..1a0cdb2c5cd 100644
--- a/src/comp/front/test.rs
+++ b/src/comp/front/test.rs
@@ -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()};
 }
 
diff --git a/src/comp/metadata/encoder.rs b/src/comp/metadata/encoder.rs
index 8c564ec627a..de1f9eacbcb 100644
--- a/src/comp/metadata/encoder.rs
+++ b/src/comp/metadata/encoder.rs
@@ -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 []]; };
diff --git a/src/comp/metadata/tydecode.rs b/src/comp/metadata/tydecode.rs
index 9e87a17537b..d67d0460753 100644
--- a/src/comp/metadata/tydecode.rs
+++ b/src/comp/metadata/tydecode.rs
@@ -145,7 +145,7 @@ fn parse_ty_constr_arg(st: @pstate, sd: str_def) ->
     }
 }
 
-fn parse_constr<copy T>(st: @pstate, sd: str_def, pser: arg_parser<T>) ->
+fn parse_constr<T: copy>(st: @pstate, sd: str_def, pser: arg_parser<T>) ->
    @ty::constr_general<T> {
     let sp = ast_util::dummy_sp(); // FIXME: use a real span
     let args: [@sp_constr_arg<T>] = [];
diff --git a/src/comp/middle/ast_map.rs b/src/comp/middle/ast_map.rs
index abf3d0cac1e..b5e53ab305a 100644
--- a/src/comp/middle/ast_map.rs
+++ b/src/comp/middle/ast_map.rs
@@ -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) {
 
diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs
index bdb76dfd921..1c74cb7b171 100644
--- a/src/comp/middle/debuginfo.rs
+++ b/src/comp/middle/debuginfo.rs
@@ -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);
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index 76a3591cd18..50f015512f4 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -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 {
diff --git a/src/comp/syntax/ast_util.rs b/src/comp/syntax/ast_util.rs
index 7a77861ae0b..121abc1ce5c 100644
--- a/src/comp/syntax/ast_util.rs
+++ b/src/comp/syntax/ast_util.rs
@@ -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)
 }
 
diff --git a/src/comp/syntax/ext/simplext.rs b/src/comp/syntax/ext/simplext.rs
index 371370c5eda..8f6f1a5828a 100644
--- a/src/comp/syntax/ext/simplext.rs
+++ b/src/comp/syntax/ext/simplext.rs
@@ -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 {
diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs
index 990132e01bf..d9edeefd44d 100644
--- a/src/comp/syntax/parse/parser.rs
+++ b/src/comp/syntax/parse/parser.rs
@@ -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 {
diff --git a/src/comp/syntax/util/interner.rs b/src/comp/syntax/util/interner.rs
index 2c1589085f2..ab411baaf5a 100644
--- a/src/comp/syntax/util/interner.rs
+++ b/src/comp/syntax/util/interner.rs
@@ -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]
     }
diff --git a/src/comp/util/common.rs b/src/comp/util/common.rs
index 03a6136656a..611949ef51d 100644
--- a/src/comp/util/common.rs
+++ b/src/comp/util/common.rs
@@ -21,7 +21,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);
diff --git a/src/comp/util/filesearch.rs b/src/comp/util/filesearch.rs
index b7942ce8f48..ce8a1d7fde0 100644
--- a/src/comp/util/filesearch.rs
+++ b/src/comp/util/filesearch.rs
@@ -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) {
diff --git a/src/fuzzer/fuzzer.rs b/src/fuzzer/fuzzer.rs
index 91cb090b83c..8e821fc45a6 100644
--- a/src/fuzzer/fuzzer.rs
+++ b/src/fuzzer/fuzzer.rs
@@ -226,7 +226,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,
diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs
index e00205a522b..d8051dfabd1 100644
--- a/src/libcore/comm.rs
+++ b/src/libcore/comm.rs
@@ -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))
 }
diff --git a/src/libcore/either.rs b/src/libcore/either.rs
index f3571ea5bcf..e6956930686 100644
--- a/src/libcore/either.rs
+++ b/src/libcore/either.rs
@@ -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) }
diff --git a/src/libcore/float.rs b/src/libcore/float.rs
index fdc5dda996d..dcc44b36605 100644
--- a/src/libcore/float.rs
+++ b/src/libcore/float.rs
@@ -467,14 +467,14 @@ 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 }
 
 /*
 Function: acos
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index e0a137ca9e8..453f38567a8 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -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) } }
 }
 
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 91038474ead..52af0421e58 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -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) }
diff --git a/src/libcore/task.rs b/src/libcore/task.rs
index 503a336f7cd..5de9c8347fe 100644
--- a/src/libcore/task.rs
+++ b/src/libcore/task.rs
@@ -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);
     }
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index 0c1db7119af..32bb2f46a49 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -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([]);
diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs
index 7c2f1be7084..4374a7ffb99 100644
--- a/src/libstd/c_vec.rs
+++ b/src/libstd/c_vec.rs
@@ -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 };
 }
diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs
index aee8beba111..86aeed3826c 100644
--- a/src/libstd/comm.rs
+++ b/src/libstd/comm.rs
@@ -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))
 }
diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs
index 8da26c55b10..05c3c6c2b0a 100644
--- a/src/libstd/deque.rs
+++ b/src/libstd/deque.rs
@@ -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>]) {
diff --git a/src/libstd/fun_treemap.rs b/src/libstd/fun_treemap.rs
index 1f4e6b9491a..046f565577a 100644
--- a/src/libstd/fun_treemap.rs
+++ b/src/libstd/fun_treemap.rs
@@ -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, _, _) {
diff --git a/src/libstd/list.rs b/src/libstd/list.rs
index aabc3499385..efd633467ef 100644
--- a/src/libstd/list.rs
+++ b/src/libstd/list.rs
@@ -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); }
diff --git a/src/libstd/map.rs b/src/libstd/map.rs
index 3b6a45b9060..db47160216c 100644
--- a/src/libstd/map.rs
+++ b/src/libstd/map.rs
@@ -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);
diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs
index 5ba1366ccb5..d40adc84739 100644
--- a/src/libstd/smallintmap.rs
+++ b/src/libstd/smallintmap.rs
@@ -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);
 }
 
diff --git a/src/libstd/sort.rs b/src/libstd/sort.rs
index 38ab4f3cfb1..190497b48dd 100644
--- a/src/libstd/sort.rs
+++ b/src/libstd/sort.rs
@@ -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,
diff --git a/src/libstd/test.rs b/src/libstd/test.rs
index 4c0a52116cc..43a869f0319 100644
--- a/src/libstd/test.rs
+++ b/src/libstd/test.rs
@@ -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 }};
diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs
index 74d40f1c05d..646fde401db 100644
--- a/src/libstd/treemap.rs
+++ b/src/libstd/treemap.rs
@@ -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, _, _) {
diff --git a/src/libstd/util.rs b/src/libstd/util.rs
index f4d984a8937..f7bfc18a257 100644
--- a/src/libstd/util.rs
+++ b/src/libstd/util.rs
@@ -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
diff --git a/src/test/bench/task-perf-word-count-generic.rs b/src/test/bench/task-perf-word-count-generic.rs
index cf8986aa0f7..e13603aec91 100644
--- a/src/test/bench/task-perf-word-count-generic.rs
+++ b/src/test/bench/task-perf-word-count-generic.rs
@@ -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);
diff --git a/src/test/compile-fail/unique-unique-kind.rs b/src/test/compile-fail/unique-unique-kind.rs
index ad172f7ae83..8845e15721f 100644
--- a/src/test/compile-fail/unique-unique-kind.rs
+++ b/src/test/compile-fail/unique-unique-kind.rs
@@ -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() {
diff --git a/src/test/compile-fail/use-after-send.rs b/src/test/compile-fail/use-after-send.rs
index 7dc3f7b4a32..858cc62a944 100644
--- a/src/test/compile-fail/use-after-send.rs
+++ b/src/test/compile-fail/use-after-send.rs
@@ -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;
diff --git a/src/test/run-fail/bug-811.rs b/src/test/run-fail/bug-811.rs
index a257a903fd2..62206f93994 100644
--- a/src/test/run-fail/bug-811.rs
+++ b/src/test/run-fail/bug-811.rs
@@ -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"; }
diff --git a/src/test/run-fail/port-type.rs b/src/test/run-fail/port-type.rs
index a43c7ce0e69..3c7ebf8c18c 100644
--- a/src/test/run-fail/port-type.rs
+++ b/src/test/run-fail/port-type.rs
@@ -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>();
diff --git a/src/test/run-pass/auto-instantiate.rs b/src/test/run-pass/auto-instantiate.rs
index ed8c71aecba..0d5429e1980 100644
--- a/src/test/run-pass/auto-instantiate.rs
+++ b/src/test/run-pass/auto-instantiate.rs
@@ -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);
diff --git a/src/test/run-pass/bind-generic.rs b/src/test/run-pass/bind-generic.rs
index e12caefe140..579b304f839 100644
--- a/src/test/run-pass/bind-generic.rs
+++ b/src/test/run-pass/bind-generic.rs
@@ -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();
 }
diff --git a/src/test/run-pass/box-unbox.rs b/src/test/run-pass/box-unbox.rs
index 61f932bb939..be9981ccdbe 100644
--- a/src/test/run-pass/box-unbox.rs
+++ b/src/test/run-pass/box-unbox.rs
@@ -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;
diff --git a/src/test/run-pass/expr-alt-generic-box2.rs b/src/test/run-pass/expr-alt-generic-box2.rs
index bc19200e323..c2f933a3480 100644
--- a/src/test/run-pass/expr-alt-generic-box2.rs
+++ b/src/test/run-pass/expr-alt-generic-box2.rs
@@ -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));
 }
diff --git a/src/test/run-pass/expr-alt-generic-unique1.rs b/src/test/run-pass/expr-alt-generic-unique1.rs
index 301d56389b1..2bbb0fea5f7 100644
--- a/src/test/run-pass/expr-alt-generic-unique1.rs
+++ b/src/test/run-pass/expr-alt-generic-unique1.rs
@@ -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));
 }
diff --git a/src/test/run-pass/expr-alt-generic-unique2.rs b/src/test/run-pass/expr-alt-generic-unique2.rs
index 5640dca0b4e..30581222bfa 100644
--- a/src/test/run-pass/expr-alt-generic-unique2.rs
+++ b/src/test/run-pass/expr-alt-generic-unique2.rs
@@ -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));
 }
diff --git a/src/test/run-pass/expr-alt-generic.rs b/src/test/run-pass/expr-alt-generic.rs
index 5a2f7d8b71c..393cb1b7a4e 100644
--- a/src/test/run-pass/expr-alt-generic.rs
+++ b/src/test/run-pass/expr-alt-generic.rs
@@ -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));
 }
diff --git a/src/test/run-pass/expr-block-generic-box2.rs b/src/test/run-pass/expr-block-generic-box2.rs
index ba98b8546a1..4ffc190716c 100644
--- a/src/test/run-pass/expr-block-generic-box2.rs
+++ b/src/test/run-pass/expr-block-generic-box2.rs
@@ -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));
 }
diff --git a/src/test/run-pass/expr-block-generic-unique1.rs b/src/test/run-pass/expr-block-generic-unique1.rs
index 8942201fa9c..060fba26051 100644
--- a/src/test/run-pass/expr-block-generic-unique1.rs
+++ b/src/test/run-pass/expr-block-generic-unique1.rs
@@ -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));
 }
diff --git a/src/test/run-pass/expr-block-generic-unique2.rs b/src/test/run-pass/expr-block-generic-unique2.rs
index fba64608186..ce6489cdd12 100644
--- a/src/test/run-pass/expr-block-generic-unique2.rs
+++ b/src/test/run-pass/expr-block-generic-unique2.rs
@@ -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));
 }
diff --git a/src/test/run-pass/expr-block-generic.rs b/src/test/run-pass/expr-block-generic.rs
index 4424d144e15..bf31ffd5808 100644
--- a/src/test/run-pass/expr-block-generic.rs
+++ b/src/test/run-pass/expr-block-generic.rs
@@ -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));
 }
diff --git a/src/test/run-pass/expr-fn.rs b/src/test/run-pass/expr-fn.rs
index 5cd3f2a178b..a3bd2449bb2 100644
--- a/src/test/run-pass/expr-fn.rs
+++ b/src/test/run-pass/expr-fn.rs
@@ -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);
 }
 
diff --git a/src/test/run-pass/expr-if-generic-box2.rs b/src/test/run-pass/expr-if-generic-box2.rs
index da00556eb4e..01daf198dfe 100644
--- a/src/test/run-pass/expr-if-generic-box2.rs
+++ b/src/test/run-pass/expr-if-generic-box2.rs
@@ -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));
 }
diff --git a/src/test/run-pass/expr-if-generic.rs b/src/test/run-pass/expr-if-generic.rs
index f98a8742cc2..9c565f35f67 100644
--- a/src/test/run-pass/expr-if-generic.rs
+++ b/src/test/run-pass/expr-if-generic.rs
@@ -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));
 }
diff --git a/src/test/run-pass/fixed-point-bind-unique.rs b/src/test/run-pass/fixed-point-bind-unique.rs
index bbfc3f53f26..dac5ffd0416 100644
--- a/src/test/run-pass/fixed-point-bind-unique.rs
+++ b/src/test/run-pass/fixed-point-bind-unique.rs
@@ -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, _);
 }
 
diff --git a/src/test/run-pass/fn-bare-spawn.rs b/src/test/run-pass/fn-bare-spawn.rs
index 59a57b8597c..ab4f40236be 100644
--- a/src/test/run-pass/fn-bare-spawn.rs
+++ b/src/test/run-pass/fn-bare-spawn.rs
@@ -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);
 }
 
diff --git a/src/test/run-pass/foreach-unique-drop.rs b/src/test/run-pass/foreach-unique-drop.rs
index 5b696a0efe9..1c8f900b2e0 100644
--- a/src/test/run-pass/foreach-unique-drop.rs
+++ b/src/test/run-pass/foreach-unique-drop.rs
@@ -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}); }
 }
 
diff --git a/src/test/run-pass/generic-alias-box.rs b/src/test/run-pass/generic-alias-box.rs
index f44ef370e2c..b9bc823a8b9 100644
--- a/src/test/run-pass/generic-alias-box.rs
+++ b/src/test/run-pass/generic-alias-box.rs
@@ -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;
diff --git a/src/test/run-pass/generic-alias-unique.rs b/src/test/run-pass/generic-alias-unique.rs
index 4746a588a56..0af9855de0d 100644
--- a/src/test/run-pass/generic-alias-unique.rs
+++ b/src/test/run-pass/generic-alias-unique.rs
@@ -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;
diff --git a/src/test/run-pass/generic-bind-2.rs b/src/test/run-pass/generic-bind-2.rs
index c633cb2d08a..eeb9cf25f8f 100644
--- a/src/test/run-pass/generic-bind-2.rs
+++ b/src/test/run-pass/generic-bind-2.rs
@@ -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};
diff --git a/src/test/run-pass/generic-bind.rs b/src/test/run-pass/generic-bind.rs
index 8464bfb0241..d0d3ea98a47 100644
--- a/src/test/run-pass/generic-bind.rs
+++ b/src/test/run-pass/generic-bind.rs
@@ -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};
diff --git a/src/test/run-pass/generic-box.rs b/src/test/run-pass/generic-box.rs
index 87465ae6a93..14fb924492a 100644
--- a/src/test/run-pass/generic-box.rs
+++ b/src/test/run-pass/generic-box.rs
@@ -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});
diff --git a/src/test/run-pass/generic-derived-type.rs b/src/test/run-pass/generic-derived-type.rs
index 032a5c3f9d6..39f4c0d1472 100644
--- a/src/test/run-pass/generic-derived-type.rs
+++ b/src/test/run-pass/generic-derived-type.rs
@@ -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};
diff --git a/src/test/run-pass/generic-drop-glue.rs b/src/test/run-pass/generic-drop-glue.rs
index ced0ecfbe9e..15583f9904b 100644
--- a/src/test/run-pass/generic-drop-glue.rs
+++ b/src/test/run-pass/generic-drop-glue.rs
@@ -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); }
diff --git a/src/test/run-pass/generic-exterior-box.rs b/src/test/run-pass/generic-exterior-box.rs
index 41315e15643..8c042a9e76d 100644
--- a/src/test/run-pass/generic-exterior-box.rs
+++ b/src/test/run-pass/generic-exterior-box.rs
@@ -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;
diff --git a/src/test/run-pass/generic-exterior-unique.rs b/src/test/run-pass/generic-exterior-unique.rs
index 1a97c134748..6f985120d42 100644
--- a/src/test/run-pass/generic-exterior-unique.rs
+++ b/src/test/run-pass/generic-exterior-unique.rs
@@ -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;
diff --git a/src/test/run-pass/generic-fn-infer.rs b/src/test/run-pass/generic-fn-infer.rs
index 57d4052e5a0..31f0008fc0b 100644
--- a/src/test/run-pass/generic-fn-infer.rs
+++ b/src/test/run-pass/generic-fn-infer.rs
@@ -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); }
diff --git a/src/test/run-pass/generic-fn-unique.rs b/src/test/run-pass/generic-fn-unique.rs
index 7333350e3b2..749341c1a19 100644
--- a/src/test/run-pass/generic-fn-unique.rs
+++ b/src/test/run-pass/generic-fn-unique.rs
@@ -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); }
diff --git a/src/test/run-pass/generic-fn.rs b/src/test/run-pass/generic-fn.rs
index ac2d6f5aad3..6f854efa857 100644
--- a/src/test/run-pass/generic-fn.rs
+++ b/src/test/run-pass/generic-fn.rs
@@ -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};
 
diff --git a/src/test/run-pass/generic-obj-with-derived-type.rs b/src/test/run-pass/generic-obj-with-derived-type.rs
index 2186b12022d..2c4e1804af5 100644
--- a/src/test/run-pass/generic-obj-with-derived-type.rs
+++ b/src/test/run-pass/generic-obj-with-derived-type.rs
@@ -1,6 +1,6 @@
 
 
-obj handle<copy T>(data: T) {
+obj handle<T: copy>(data: T) {
     fn get() -> T { ret data; }
 }
 
diff --git a/src/test/run-pass/generic-obj.rs b/src/test/run-pass/generic-obj.rs
index ab693787182..5eedeecb5bc 100644
--- a/src/test/run-pass/generic-obj.rs
+++ b/src/test/run-pass/generic-obj.rs
@@ -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;
diff --git a/src/test/run-pass/generic-tup.rs b/src/test/run-pass/generic-tup.rs
index 2b5f81d526d..58a33b80946 100644
--- a/src/test/run-pass/generic-tup.rs
+++ b/src/test/run-pass/generic-tup.rs
@@ -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)));
diff --git a/src/test/run-pass/generic-unique.rs b/src/test/run-pass/generic-unique.rs
index 3b6b19ce450..686bd36888e 100644
--- a/src/test/run-pass/generic-unique.rs
+++ b/src/test/run-pass/generic-unique.rs
@@ -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});
diff --git a/src/test/run-pass/issue-333.rs b/src/test/run-pass/issue-333.rs
index 793df760b4b..be253b9afdd 100644
--- a/src/test/run-pass/issue-333.rs
+++ b/src/test/run-pass/issue-333.rs
@@ -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); }
diff --git a/src/test/run-pass/ivec-add.rs b/src/test/run-pass/ivec-add.rs
index 9e45b028386..e79ca8bae38 100644
--- a/src/test/run-pass/ivec-add.rs
+++ b/src/test/run-pass/ivec-add.rs
@@ -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]; }
 
diff --git a/src/test/run-pass/newtype-polymorphic.rs b/src/test/run-pass/newtype-polymorphic.rs
index 5bb2171dfd2..f25665ca86c 100644
--- a/src/test/run-pass/newtype-polymorphic.rs
+++ b/src/test/run-pass/newtype-polymorphic.rs
@@ -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]);
diff --git a/src/test/run-pass/non-boolean-pure-fns.rs b/src/test/run-pass/non-boolean-pure-fns.rs
index 27f3b530154..d74fb81a3b9 100644
--- a/src/test/run-pass/non-boolean-pure-fns.rs
+++ b/src/test/run-pass/non-boolean-pure-fns.rs
@@ -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);
 }
diff --git a/src/test/run-pass/obj-return-polytypes.rs b/src/test/run-pass/obj-return-polytypes.rs
index ebfcf37e79d..4c1f8d54ced 100644
--- a/src/test/run-pass/obj-return-polytypes.rs
+++ b/src/test/run-pass/obj-return-polytypes.rs
@@ -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>(); }
 }
 
diff --git a/src/test/run-pass/ret-none.rs b/src/test/run-pass/ret-none.rs
index fe91c15c72d..7481bfe9100 100644
--- a/src/test/run-pass/ret-none.rs
+++ b/src/test/run-pass/ret-none.rs
@@ -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>(); }
diff --git a/src/test/run-pass/send-type-inference.rs b/src/test/run-pass/send-type-inference.rs
index 1c88d0182f6..432985bcb7f 100644
--- a/src/test/run-pass/send-type-inference.rs
+++ b/src/test/run-pass/send-type-inference.rs
@@ -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));
 }
diff --git a/src/test/run-pass/sendfn-generic-fn.rs b/src/test/run-pass/sendfn-generic-fn.rs
index 3c19958fa31..66177fd04ae 100644
--- a/src/test/run-pass/sendfn-generic-fn.rs
+++ b/src/test/run-pass/sendfn-generic-fn.rs
@@ -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);
     };
diff --git a/src/test/run-pass/type-param-constraints.rs b/src/test/run-pass/type-param-constraints.rs
index def6e72f4d9..7fdaa061ee6 100644
--- a/src/test/run-pass/type-param-constraints.rs
+++ b/src/test/run-pass/type-param-constraints.rs
@@ -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) { }
 
diff --git a/src/test/run-pass/unchecked-predicates.rs b/src/test/run-pass/unchecked-predicates.rs
index 035b18f8051..e43cdaacb8b 100644
--- a/src/test/run-pass/unchecked-predicates.rs
+++ b/src/test/run-pass/unchecked-predicates.rs
@@ -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)
 }
diff --git a/src/test/run-pass/unique-assign-generic.rs b/src/test/run-pass/unique-assign-generic.rs
index 372cca1c667..ba8b4bb5723 100644
--- a/src/test/run-pass/unique-assign-generic.rs
+++ b/src/test/run-pass/unique-assign-generic.rs
@@ -1,4 +1,4 @@
-fn f<copy T>(t: T) -> T {
+fn f<T: copy>(t: T) -> T {
     let t1 = t;
     t1
 }
diff --git a/src/test/run-pass/unique-generic-assign.rs b/src/test/run-pass/unique-generic-assign.rs
index 4370bb4a791..f8fd6f62c26 100644
--- a/src/test/run-pass/unique-generic-assign.rs
+++ b/src/test/run-pass/unique-generic-assign.rs
@@ -1,6 +1,6 @@
 // Issue #976
 
-fn f<copy T>(x: ~T) {
+fn f<T: copy>(x: ~T) {
     let _x2 = x;
 }
 fn main() { }
diff --git a/src/test/run-pass/unique-kinds.rs b/src/test/run-pass/unique-kinds.rs
index ab88437331c..4600081e45a 100644
--- a/src/test/run-pass/unique-kinds.rs
+++ b/src/test/run-pass/unique-kinds.rs
@@ -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;
     }
 
diff --git a/src/test/run-pass/vec-push.rs b/src/test/run-pass/vec-push.rs
index 92da692e482..bf6b7638eac 100644
--- a/src/test/run-pass/vec-push.rs
+++ b/src/test/run-pass/vec-push.rs
@@ -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); }
diff --git a/src/test/stdtest/deque.rs b/src/test/stdtest/deque.rs
index a94b1739b32..ef763131a41 100644
--- a/src/test/stdtest/deque.rs
+++ b/src/test/stdtest/deque.rs
@@ -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);
diff --git a/src/test/stdtest/task.rs b/src/test/stdtest/task.rs
index 31299e703be..3a08606f47e 100644
--- a/src/test/stdtest/task.rs
+++ b/src/test/stdtest/task.rs
@@ -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);*/