about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2013-01-10 10:59:58 -0800
committerNiko Matsakis <niko@alum.mit.edu>2013-01-31 12:09:00 -0800
commit0682ad0eb9a6b268498a81b2e16a40544e44f0fa (patch)
tree694819bae28cd319401c121afa4daa00adcbdde2 /src/libsyntax
parent42b462e0765f02fd7bb0f2613240ae2489a47fee (diff)
downloadrust-0682ad0eb9a6b268498a81b2e16a40544e44f0fa.tar.gz
rust-0682ad0eb9a6b268498a81b2e16a40544e44f0fa.zip
Finalize moves-based-on-type implementation.
Changes:

- Refactor move mode computation
- Removes move mode arguments, unary move, capture clauses
  (though they still parse for backwards compatibility)
- Simplify how moves are handled in trans
- Fix a number of illegal copies that cropped up
- Workaround for bug involving def-ids in params
  (see details below)

Future work (I'll open bugs for these...):

- Improve error messages for moves that are due
  to bindings
- Add support for moving owned content like a.b.c
  to borrow check, test in trans (but I think it'll
  "just work")
- Proper fix for def-ids in params

Def ids in params:

Move captures into a map instead of recomputing.

This is a workaround for a larger bug having to do with the def-ids associated
with ty_params, which are not always properly preserved when inlining.  I am
not sure of my preferred fix for the larger bug yet.  This current fix removes
the only code in trans that I know of which relies on ty_param def-ids, but
feels fragile.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs65
-rw-r--r--src/libsyntax/ast_util.rs9
-rw-r--r--src/libsyntax/attr.rs4
-rw-r--r--src/libsyntax/ext/auto_encode.rs9
-rw-r--r--src/libsyntax/ext/build.rs7
-rw-r--r--src/libsyntax/ext/pipes/ast_builder.rs12
-rw-r--r--src/libsyntax/fold.rs27
-rw-r--r--src/libsyntax/parse/parser.rs141
-rw-r--r--src/libsyntax/print/pprust.rs47
-rw-r--r--src/libsyntax/visit.rs13
10 files changed, 103 insertions, 231 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 0b250c2e421..435e514df44 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -337,9 +337,9 @@ pub struct field_pat {
 
 #[auto_encode]
 #[auto_decode]
+#[deriving_eq]
 pub enum binding_mode {
-    bind_by_value,
-    bind_by_move,
+    bind_by_copy,
     bind_by_ref(mutability),
     bind_infer
 }
@@ -347,51 +347,17 @@ pub enum binding_mode {
 pub impl binding_mode : to_bytes::IterBytes {
     pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
         match *self {
-          bind_by_value => 0u8.iter_bytes(lsb0, f),
-
-          bind_by_move => 1u8.iter_bytes(lsb0, f),
+          bind_by_copy => 0u8.iter_bytes(lsb0, f),
 
           bind_by_ref(ref m) =>
-          to_bytes::iter_bytes_2(&2u8, m, lsb0, f),
+          to_bytes::iter_bytes_2(&1u8, m, lsb0, f),
 
           bind_infer =>
-          3u8.iter_bytes(lsb0, f),
+          2u8.iter_bytes(lsb0, f),
         }
     }
 }
 
-pub impl binding_mode : cmp::Eq {
-    pure fn eq(&self, other: &binding_mode) -> bool {
-        match (*self) {
-            bind_by_value => {
-                match (*other) {
-                    bind_by_value => true,
-                    _ => false
-                }
-            }
-            bind_by_move => {
-                match (*other) {
-                    bind_by_move => true,
-                    _ => false
-                }
-            }
-            bind_by_ref(e0a) => {
-                match (*other) {
-                    bind_by_ref(e0b) => e0a == e0b,
-                    _ => false
-                }
-            }
-            bind_infer => {
-                match (*other) {
-                    bind_infer => true,
-                    _ => false
-                }
-            }
-        }
-    }
-    pure fn ne(&self, other: &binding_mode) -> bool { !(*self).eq(other) }
-}
-
 #[auto_encode]
 #[auto_decode]
 pub enum pat_ {
@@ -603,7 +569,7 @@ pub impl<T:cmp::Eq> inferable<T> : cmp::Eq {
 // "resolved" mode: the real modes.
 #[auto_encode]
 #[auto_decode]
-pub enum rmode { by_ref, by_val, by_move, by_copy }
+pub enum rmode { by_ref, by_val, by_copy }
 
 pub impl rmode : to_bytes::IterBytes {
     pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
@@ -729,8 +695,8 @@ pub enum expr_ {
        (implicit) condition is always true. */
     expr_loop(blk, Option<ident>),
     expr_match(@expr, ~[arm]),
-    expr_fn(Proto, fn_decl, blk, capture_clause),
-    expr_fn_block(fn_decl, blk, capture_clause),
+    expr_fn(Proto, fn_decl, blk),
+    expr_fn_block(fn_decl, blk),
     // Inner expr is always an expr_fn_block. We need the wrapping node to
     // easily type this (a function returning nil on the inside but bool on
     // the outside).
@@ -740,7 +706,6 @@ pub enum expr_ {
     expr_block(blk),
 
     expr_copy(@expr),
-    expr_unary_move(@expr),
     expr_assign(@expr, @expr),
     expr_swap(@expr, @expr),
     expr_assign_op(binop, @expr, @expr),
@@ -769,20 +734,6 @@ pub enum expr_ {
     expr_paren(@expr)
 }
 
-#[auto_encode]
-#[auto_decode]
-pub struct capture_item_ {
-    id: int,
-    is_move: bool,
-    name: ident, // Currently, can only capture a local var.
-    span: span,
-}
-
-pub type capture_item = @capture_item_;
-
-pub type capture_clause = @~[capture_item];
-
-//
 // When the main rust parser encounters a syntax-extension invocation, it
 // parses the arguments to the invocation as a token-tree. This is a very
 // loose structure, such that all sorts of different AST-fragments can
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 7b742019f0e..1ae23240404 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -256,7 +256,7 @@ pub fn ident_to_path(s: span, +i: ident) -> @path {
 
 pub fn ident_to_pat(id: node_id, s: span, +i: ident) -> @pat {
     @ast::pat { id: id,
-                node: pat_ident(bind_by_value, ident_to_path(s, i), None),
+                node: pat_ident(bind_by_copy, ident_to_path(s, i), None),
                 span: s }
 }
 
@@ -503,11 +503,8 @@ pub fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> {
                     vfn(m.self_id);
                     for vec::each(tps) |tp| { vfn(tp.id); }
                 }
-                visit::fk_anon(_, capture_clause) |
-                visit::fk_fn_block(capture_clause) => {
-                    for vec::each(*capture_clause) |clause| {
-                        vfn(clause.id);
-                    }
+                visit::fk_anon(_) |
+                visit::fk_fn_block => {
                 }
             }
 
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index 60b1b98915f..dd6a996b730 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -173,8 +173,8 @@ pub fn find_meta_items_by_name(metas: &[@ast::meta_item], name: &str) ->
  * Returns true if a list of meta items contains another meta item. The
  * comparison is performed structurally.
  */
-pub fn contains(haystack: ~[@ast::meta_item], needle: @ast::meta_item)
-             -> bool {
+pub fn contains(haystack: &[@ast::meta_item],
+                needle: @ast::meta_item) -> bool {
     for haystack.each |item| {
         if eq(*item, needle) { return true; }
     }
diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs
index e4ad518cc80..a2484e2d6df 100644
--- a/src/libsyntax/ext/auto_encode.rs
+++ b/src/libsyntax/ext/auto_encode.rs
@@ -569,7 +569,7 @@ fn mk_ser_method(
         pat: @ast::pat {
             id: cx.next_id(),
             node: ast::pat_ident(
-                ast::bind_by_value,
+                ast::bind_by_copy,
                 ast_util::ident_to_path(span, cx.ident_of(~"__s")),
                 None),
             span: span,
@@ -633,7 +633,7 @@ fn mk_deser_method(
         pat: @ast::pat {
             id: cx.next_id(),
             node: ast::pat_ident(
-                ast::bind_by_value,
+                ast::bind_by_copy,
                 ast_util::ident_to_path(span, cx.ident_of(~"__d")),
                 None),
             span: span,
@@ -1095,7 +1095,7 @@ fn mk_enum_deser_body(
                     pat: @ast::pat {
                         id: cx.next_id(),
                         node: ast::pat_ident(
-                            ast::bind_by_value,
+                            ast::bind_by_copy,
                             ast_util::ident_to_path(span, cx.ident_of(~"i")),
                             None),
                         span: span,
@@ -1114,8 +1114,7 @@ fn mk_enum_deser_body(
                     span,
                     ast::expr_match(cx.expr_var(span, ~"i"), arms)
                 )
-            ),
-            @~[]
+            )
         )
     );
 
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index d4da5a2034e..6d44a412742 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -203,7 +203,7 @@ pub fn mk_local(cx: ext_ctxt, sp: span, mutbl: bool,
     let pat = @ast::pat {
         id: cx.next_id(),
         node: ast::pat_ident(
-            ast::bind_by_value,
+            ast::bind_by_copy,
             mk_raw_path(sp, ~[ident]),
             None),
         span: sp,
@@ -279,9 +279,8 @@ pub fn mk_pat(cx: ext_ctxt, span: span, +pat: ast::pat_) -> @ast::pat {
 }
 pub fn mk_pat_ident(cx: ext_ctxt,
                     span: span,
-                    ident: ast::ident)
-                 -> @ast::pat {
-    mk_pat_ident_with_binding_mode(cx, span, ident, ast::bind_by_value)
+                    ident: ast::ident) -> @ast::pat {
+    mk_pat_ident_with_binding_mode(cx, span, ident, ast::bind_by_copy)
 }
 pub fn mk_pat_ident_with_binding_mode(cx: ext_ctxt,
                                       span: span,
diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs
index a85898390a4..8abca3d97f9 100644
--- a/src/libsyntax/ext/pipes/ast_builder.rs
+++ b/src/libsyntax/ext/pipes/ast_builder.rs
@@ -105,7 +105,6 @@ pub trait ext_ctxt_ast_builder {
     fn stmt_let(ident: ident, e: @ast::expr) -> @ast::stmt;
     fn stmt_expr(e: @ast::expr) -> @ast::stmt;
     fn block_expr(b: ast::blk) -> @ast::expr;
-    fn move_expr(e: @ast::expr) -> @ast::expr;
     fn ty_option(ty: @ast::Ty) -> @ast::Ty;
     fn ty_infer() -> @ast::Ty;
     fn ty_nil_ast_builder() -> @ast::Ty;
@@ -130,15 +129,6 @@ pub impl ext_ctxt: ext_ctxt_ast_builder {
         }
     }
 
-    fn move_expr(e: @ast::expr) -> @ast::expr {
-        @expr {
-            id: self.next_id(),
-            callee_id: self.next_id(),
-            node: ast::expr_unary_move(e),
-            span: e.span,
-        }
-    }
-
     fn stmt_expr(e: @ast::expr) -> @ast::stmt {
         @spanned { node: ast::stmt_expr(e, self.next_id()),
                    span: dummy_sp()}
@@ -205,7 +195,7 @@ pub impl ext_ctxt: ext_ctxt_ast_builder {
             pat: @ast::pat {
                 id: self.next_id(),
                 node: ast::pat_ident(
-                    ast::bind_by_value,
+                    ast::bind_by_copy,
                     ast_util::ident_to_path(dummy_sp(), name),
                     None),
                 span: dummy_sp(),
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index e8557558f17..2c2ecb91e21 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -466,30 +466,17 @@ pub fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
             expr_match(fld.fold_expr(expr),
                      vec::map((*arms), |x| fld.fold_arm(*x)))
           }
-          expr_fn(proto, decl, ref body, captures) => {
-            let captures = do captures.map |cap_item| {
-                @ast::capture_item_ {
-                    id: fld.new_id(cap_item.id),
-                    ..**cap_item
-                }
-            };
-            expr_fn(proto, fold_fn_decl(decl, fld),
-                    fld.fold_block((*body)),
-                    @captures)
+          expr_fn(proto, decl, ref body) => {
+            expr_fn(proto,
+                    fold_fn_decl(decl, fld),
+                    fld.fold_block(*body))
           }
-          expr_fn_block(decl, ref body, captures) => {
-            let captures = do captures.map |cap_item| {
-                @ast::capture_item_ {
-                    id: fld.new_id(cap_item.id),
-                    ..**cap_item
-                }
-            };
-            expr_fn_block(fold_fn_decl(decl, fld), fld.fold_block((*body)),
-                          @captures)
+          expr_fn_block(decl, ref body) => {
+            expr_fn_block(fold_fn_decl(decl, fld),
+                          fld.fold_block(*body))
           }
           expr_block(ref blk) => expr_block(fld.fold_block((*blk))),
           expr_copy(e) => expr_copy(fld.fold_expr(e)),
-          expr_unary_move(e) => expr_unary_move(fld.fold_expr(e)),
           expr_assign(el, er) => {
             expr_assign(fld.fold_expr(el), fld.fold_expr(er))
           }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index d41fedebde3..81393310cda 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -13,9 +13,9 @@ use core::prelude::*;
 use ast::{ProtoBox, ProtoUniq, RegionTyParamBound, TraitTyParamBound};
 use ast::{provided, public, pure_fn, purity, re_static};
 use ast::{_mod, add, arg, arm, attribute, bind_by_ref, bind_infer};
-use ast::{bind_by_value, bind_by_move, bitand, bitor, bitxor, blk};
-use ast::{blk_check_mode, box, by_copy, by_move, by_ref, by_val};
-use ast::{capture_clause, capture_item, crate, crate_cfg, decl, decl_item};
+use ast::{bind_by_copy, bitand, bitor, bitxor, blk};
+use ast::{blk_check_mode, box, by_copy, by_ref, by_val};
+use ast::{crate, crate_cfg, decl, decl_item};
 use ast::{decl_local, default_blk, deref, div, enum_def, enum_variant_kind};
 use ast::{expl, expr, expr_, expr_addr_of, expr_match, expr_again};
 use ast::{expr_assert, expr_assign, expr_assign_op, expr_binary, expr_block};
@@ -24,7 +24,7 @@ use ast::{expr_fail, expr_field, expr_fn, expr_fn_block, expr_if, expr_index};
 use ast::{expr_lit, expr_log, expr_loop, expr_loop_body, expr_mac};
 use ast::{expr_method_call, expr_paren, expr_path, expr_rec, expr_repeat};
 use ast::{expr_ret, expr_swap, expr_struct, expr_tup, expr_unary};
-use ast::{expr_unary_move, expr_vec, expr_vstore, expr_vstore_mut_box};
+use ast::{expr_vec, expr_vstore, expr_vstore_mut_box};
 use ast::{expr_vstore_fixed, expr_vstore_slice, expr_vstore_box};
 use ast::{expr_vstore_mut_slice, expr_while, extern_fn, field, fn_decl};
 use ast::{expr_vstore_uniq, TyFn, Onceness, Once, Many};
@@ -102,7 +102,7 @@ enum restriction {
 enum class_contents { dtor_decl(blk, ~[attribute], codemap::span),
                       members(~[@struct_field]) }
 
-type arg_or_capture_item = Either<arg, capture_item>;
+type arg_or_capture_item = Either<arg, ()>;
 type item_info = (ident, item_, Option<~[attribute]>);
 
 pub enum item_or_view_item {
@@ -401,7 +401,7 @@ pub impl Parser {
 
             let tps = p.parse_ty_params();
 
-            let (self_ty, d, _) = do self.parse_fn_decl_with_self() |p| {
+            let (self_ty, d) = do self.parse_fn_decl_with_self() |p| {
                 // This is somewhat dubious; We don't want to allow argument
                 // names to be left off if there is a definition...
                 either::Left(p.parse_arg_general(false))
@@ -651,7 +651,7 @@ pub impl Parser {
 
     fn parse_arg_mode() -> mode {
         if self.eat(token::BINOP(token::MINUS)) {
-            expl(by_move)
+            expl(by_copy) // NDM outdated syntax
         } else if self.eat(token::ANDAND) {
             expl(by_ref)
         } else if self.eat(token::BINOP(token::PLUS)) {
@@ -689,23 +689,12 @@ pub impl Parser {
     }
 
     fn parse_capture_item_or(parse_arg_fn: fn(Parser) -> arg_or_capture_item)
-        -> arg_or_capture_item {
-
-        fn parse_capture_item(p:Parser, is_move: bool) -> capture_item {
-            let sp = mk_sp(p.span.lo, p.span.hi);
-            let ident = p.parse_ident();
-            @ast::capture_item_ {
-                id: p.get_id(),
-                is_move: is_move,
-                name: ident,
-                span: sp,
-            }
-        }
-
-        if self.eat_keyword(~"move") {
-            either::Right(parse_capture_item(self, true))
-        } else if self.eat_keyword(~"copy") {
-            either::Right(parse_capture_item(self, false))
+        -> arg_or_capture_item
+    {
+        if self.eat_keyword(~"move") || self.eat_keyword(~"copy") {
+            // XXX outdated syntax now that moves-based-on-type has gone in
+            self.parse_ident();
+            either::Right(())
         } else {
             parse_arg_fn(self)
         }
@@ -1078,9 +1067,8 @@ pub impl Parser {
             ex = expr_copy(e);
             hi = e.span.hi;
         } else if self.eat_keyword(~"move") {
-            let e = self.parse_expr();
-            ex = expr_unary_move(e);
-            hi = e.span.hi;
+            // XXX move keyword is no longer important, remove after snapshot
+            return self.parse_expr();
         } else if self.token == token::MOD_SEP ||
             is_ident(self.token) && !self.is_keyword(~"true") &&
             !self.is_keyword(~"false") {
@@ -1576,12 +1564,10 @@ pub impl Parser {
 
         // if we want to allow fn expression argument types to be inferred in
         // the future, just have to change parse_arg to parse_fn_block_arg.
-        let (decl, capture_clause) =
-            self.parse_fn_decl(|p| p.parse_arg_or_capture_item());
+        let decl = self.parse_fn_decl(|p| p.parse_arg_or_capture_item());
 
         let body = self.parse_block();
-        return self.mk_expr(lo, body.span.hi,
-                         expr_fn(proto, decl, body, capture_clause));
+        return self.mk_expr(lo, body.span.hi,expr_fn(proto, decl, body));
     }
 
     // `|args| { ... }` like in `do` expressions
@@ -1594,18 +1580,15 @@ pub impl Parser {
                   }
                   _ => {
                     // No argument list - `do foo {`
-                    (
-                        ast::fn_decl {
-                            inputs: ~[],
-                            output: @Ty {
-                                id: self.get_id(),
-                                node: ty_infer,
-                                span: self.span
-                            },
-                            cf: return_val
-                        },
-                        @~[]
-                    )
+                      ast::fn_decl {
+                          inputs: ~[],
+                          output: @Ty {
+                              id: self.get_id(),
+                              node: ty_infer,
+                              span: self.span
+                          },
+                          cf: return_val
+                      }
                   }
                 }
             },
@@ -1621,10 +1604,10 @@ pub impl Parser {
                                 || self.parse_expr())
     }
 
-    fn parse_lambda_expr_(parse_decl: fn&() -> (fn_decl, capture_clause),
+    fn parse_lambda_expr_(parse_decl: fn&() -> fn_decl,
                           parse_body: fn&() -> @expr) -> @expr {
         let lo = self.last_span.lo;
-        let (decl, captures) = parse_decl();
+        let decl = parse_decl();
         let body = parse_body();
         let fakeblock = ast::blk_ {
             view_items: ~[],
@@ -1636,7 +1619,7 @@ pub impl Parser {
         let fakeblock = spanned(body.span.lo, body.span.hi,
                                 fakeblock);
         return self.mk_expr(lo, body.span.hi,
-                         expr_fn_block(decl, fakeblock, captures));
+                            expr_fn_block(decl, fakeblock));
     }
 
     fn parse_else_expr() -> @expr {
@@ -2065,22 +2048,16 @@ pub impl Parser {
                 let mutbl = self.parse_mutability();
                 pat = self.parse_pat_ident(refutable, bind_by_ref(mutbl));
             } else if self.eat_keyword(~"copy") {
-                pat = self.parse_pat_ident(refutable, bind_by_value);
-            } else if self.eat_keyword(~"move") {
-                pat = self.parse_pat_ident(refutable, bind_by_move);
+                pat = self.parse_pat_ident(refutable, bind_by_copy);
             } else {
-                let binding_mode;
-                // XXX: Aren't these two cases deadcode? -- bblum
-                if self.eat_keyword(~"copy") {
-                    binding_mode = bind_by_value;
-                } else if self.eat_keyword(~"move") {
-                    binding_mode = bind_by_move;
-                } else if refutable {
-                    binding_mode = bind_infer;
-                } else {
-                    binding_mode = bind_by_value;
+                if self.eat_keyword(~"move") {
+                    /* XXX---remove move keyword */
                 }
 
+                // XXX---refutable match bindings should work same as let
+                let binding_mode =
+                    if refutable {bind_infer} else {bind_by_copy};
+
                 let cannot_be_enum_or_struct;
                 match self.look_ahead(1) {
                     token::LPAREN | token::LBRACKET | token::LT |
@@ -2560,25 +2537,21 @@ pub impl Parser {
     }
 
     fn parse_fn_decl(parse_arg_fn: fn(Parser) -> arg_or_capture_item)
-        -> (fn_decl, capture_clause) {
-
+        -> fn_decl
+    {
         let args_or_capture_items: ~[arg_or_capture_item] =
             self.parse_unspanned_seq(
                 token::LPAREN, token::RPAREN,
                 seq_sep_trailing_disallowed(token::COMMA), parse_arg_fn);
 
         let inputs = either::lefts(args_or_capture_items);
-        let capture_clause = @either::rights(args_or_capture_items);
 
         let (ret_style, ret_ty) = self.parse_ret_ty();
-        (
-            ast::fn_decl {
-                inputs: inputs,
-                output: ret_ty,
-                cf: ret_style,
-            },
-            capture_clause
-        )
+        ast::fn_decl {
+            inputs: inputs,
+            output: ret_ty,
+            cf: ret_style,
+        }
     }
 
     fn is_self_ident() -> bool {
@@ -2598,8 +2571,8 @@ pub impl Parser {
     }
 
     fn parse_fn_decl_with_self(parse_arg_fn:
-                                    fn(Parser) -> arg_or_capture_item)
-                            -> (self_ty, fn_decl, capture_clause) {
+                               fn(Parser) -> arg_or_capture_item)
+                            -> (self_ty, fn_decl) {
 
         fn maybe_parse_self_ty(cnstr: fn(+v: mutability) -> ast::self_ty_,
                                p: Parser) -> ast::self_ty_ {
@@ -2675,7 +2648,6 @@ pub impl Parser {
         let hi = self.span.hi;
 
         let inputs = either::lefts(args_or_capture_items);
-        let capture_clause = @either::rights(args_or_capture_items);
         let (ret_style, ret_ty) = self.parse_ret_ty();
 
         let fn_decl = ast::fn_decl {
@@ -2684,10 +2656,10 @@ pub impl Parser {
             cf: ret_style
         };
 
-        (spanned(lo, hi, self_ty), fn_decl, capture_clause)
+        (spanned(lo, hi, self_ty), fn_decl)
     }
 
-    fn parse_fn_block_decl() -> (fn_decl, capture_clause) {
+    fn parse_fn_block_decl() -> fn_decl {
         let inputs_captures = {
             if self.eat(token::OROR) {
                 ~[]
@@ -2704,14 +2676,11 @@ pub impl Parser {
             @Ty { id: self.get_id(), node: ty_infer, span: self.span }
         };
 
-        (
-            ast::fn_decl {
-                inputs: either::lefts(inputs_captures),
-                output: output,
-                cf: return_val,
-            },
-            @either::rights(inputs_captures)
-        )
+        ast::fn_decl {
+            inputs: either::lefts(inputs_captures),
+            output: output,
+            cf: return_val,
+        }
     }
 
     fn parse_fn_header() -> {ident: ident, tps: ~[ty_param]} {
@@ -2733,7 +2702,7 @@ pub impl Parser {
 
     fn parse_item_fn(purity: purity) -> item_info {
         let t = self.parse_fn_header();
-        let (decl, _) = self.parse_fn_decl(|p| p.parse_arg());
+        let decl = self.parse_fn_decl(|p| p.parse_arg());
         let (inner_attrs, body) = self.parse_inner_attrs_and_block(true);
         (t.ident, item_fn(decl, purity, t.tps, body), Some(inner_attrs))
     }
@@ -2753,7 +2722,7 @@ pub impl Parser {
         let pur = self.parse_fn_purity();
         let ident = self.parse_method_name();
         let tps = self.parse_ty_params();
-        let (self_ty, decl, _) = do self.parse_fn_decl_with_self() |p| {
+        let (self_ty, decl) = do self.parse_fn_decl_with_self() |p| {
             p.parse_arg()
         };
         // XXX: interaction between staticness, self_ty is broken now
@@ -3262,7 +3231,7 @@ pub impl Parser {
         let vis = self.parse_visibility();
         let purity = self.parse_fn_purity();
         let t = self.parse_fn_header();
-        let (decl, _) = self.parse_fn_decl(|p| p.parse_arg());
+        let decl = self.parse_fn_decl(|p| p.parse_arg());
         let mut hi = self.span.hi;
         self.expect(token::SEMI);
         @ast::foreign_item { ident: t.ident,
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 7f03158a4df..39fb98aea26 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1305,24 +1305,24 @@ pub fn print_expr(s: ps, &&expr: @ast::expr) {
         }
         bclose_(s, expr.span, match_indent_unit);
       }
-      ast::expr_fn(proto, decl, ref body, cap_clause) => {
+      ast::expr_fn(proto, decl, ref body) => {
         // containing cbox, will be closed by print-block at }
         cbox(s, indent_unit);
         // head-box, will be closed by print-block at start
         ibox(s, 0u);
         print_fn_header_info(s, None, None, ast::Many,
                              Some(proto), ast::inherited);
-        print_fn_args_and_ret(s, decl, *cap_clause, None);
+        print_fn_args_and_ret(s, decl, None);
         space(s.s);
         print_block(s, (*body));
       }
-      ast::expr_fn_block(decl, ref body, cap_clause) => {
+      ast::expr_fn_block(decl, ref body) => {
         // in do/for blocks we don't want to show an empty
         // argument list, but at this point we don't know which
         // we are inside.
         //
         // if !decl.inputs.is_empty() {
-        print_fn_block_args(s, decl, *cap_clause);
+        print_fn_block_args(s, decl);
         space(s.s);
         // }
         assert (*body).node.stmts.is_empty();
@@ -1357,10 +1357,6 @@ pub fn print_expr(s: ps, &&expr: @ast::expr) {
         print_block(s, (*blk));
       }
       ast::expr_copy(e) => { word_space(s, ~"copy"); print_expr(s, e); }
-      ast::expr_unary_move(e) => {
-          word_space(s, ~"move");
-          print_expr(s, e);
-      }
       ast::expr_assign(lhs, rhs) => {
         print_expr(s, lhs);
         space(s.s);
@@ -1554,10 +1550,7 @@ pub fn print_pat(s: ps, &&pat: @ast::pat, refutable: bool) {
                       word_nbsp(s, ~"ref");
                       print_mutability(s, mutbl);
                   }
-                  ast::bind_by_move => {
-                      word_nbsp(s, ~"move");
-                  }
-                  ast::bind_by_value => {
+                  ast::bind_by_copy => {
                       word_nbsp(s, ~"copy");
                   }
                   ast::bind_infer => {}
@@ -1693,16 +1686,14 @@ pub fn print_fn(s: ps,
     nbsp(s);
     print_ident(s, name);
     print_type_params(s, typarams);
-    print_fn_args_and_ret(s, decl, ~[], opt_self_ty);
+    print_fn_args_and_ret(s, decl, opt_self_ty);
 }
 
 pub fn print_fn_args(s: ps, decl: ast::fn_decl,
-                     cap_items: ~[ast::capture_item],
-                     opt_self_ty: Option<ast::self_ty_>) {
-    // It is unfortunate to duplicate the commasep logic, but we
-    // we want the self type, the args, and the capture clauses all
-    // in the same box.
-    box(s, 0, inconsistent);
+                 opt_self_ty: Option<ast::self_ty_>) {
+    // It is unfortunate to duplicate the commasep logic, but we we want the
+    // self type and the args all in the same box.
+    box(s, 0u, inconsistent);
     let mut first = true;
     for opt_self_ty.each |self_ty| {
         first = !print_self_ty(s, *self_ty);
@@ -1713,21 +1704,13 @@ pub fn print_fn_args(s: ps, decl: ast::fn_decl,
         print_arg(s, *arg);
     }
 
-    for cap_items.each |cap_item| {
-        if first { first = false; } else { word_space(s, ~","); }
-        if cap_item.is_move { word_nbsp(s, ~"move") }
-        else { word_nbsp(s, ~"copy") }
-        print_ident(s, cap_item.name);
-    }
-
     end(s);
 }
 
 pub fn print_fn_args_and_ret(s: ps, decl: ast::fn_decl,
-                             cap_items: ~[ast::capture_item],
                              opt_self_ty: Option<ast::self_ty_>) {
     popen(s);
-    print_fn_args(s, decl, cap_items, opt_self_ty);
+    print_fn_args(s, decl, opt_self_ty);
     pclose(s);
 
     maybe_print_comment(s, decl.output.span.lo);
@@ -1741,10 +1724,9 @@ pub fn print_fn_args_and_ret(s: ps, decl: ast::fn_decl,
     }
 }
 
-pub fn print_fn_block_args(s: ps, decl: ast::fn_decl,
-                           cap_items: ~[ast::capture_item]) {
+pub fn print_fn_block_args(s: ps, decl: ast::fn_decl) {
     word(s.s, ~"|");
-    print_fn_args(s, decl, cap_items, None);
+    print_fn_args(s, decl, None);
     word(s.s, ~"|");
 
     match decl.output.node {
@@ -1761,10 +1743,9 @@ pub fn print_fn_block_args(s: ps, decl: ast::fn_decl,
 
 pub fn mode_to_str(m: ast::mode) -> ~str {
     match m {
-      ast::expl(ast::by_move) => ~"-",
       ast::expl(ast::by_ref) => ~"&&",
-      ast::expl(ast::by_val) => ~"++",
       ast::expl(ast::by_copy) => ~"+",
+      ast::expl(ast::by_val) => ~"++",
       ast::infer(_) => ~""
     }
 }
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 196ee349b79..dd7f274b5ba 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -32,8 +32,8 @@ pub enum vt<E> { mk_vt(visitor<E>), }
 pub enum fn_kind {
     fk_item_fn(ident, ~[ty_param], purity), //< an item declared with fn()
     fk_method(ident, ~[ty_param], @method),
-    fk_anon(Proto, capture_clause),  //< an anonymous function like fn@(...)
-    fk_fn_block(capture_clause),     //< a block {||...}
+    fk_anon(Proto),    //< an anonymous function like fn@(...)
+    fk_fn_block,       //< a block {||...}
     fk_dtor(~[ty_param], ~[attribute], node_id /* self id */,
             def_id /* parent class id */) // class destructor
 
@@ -457,12 +457,12 @@ pub fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
         (v.visit_expr)(x, e, v);
         for (*arms).each |a| { (v.visit_arm)(*a, e, v); }
       }
-      expr_fn(proto, decl, ref body, cap_clause) => {
-        (v.visit_fn)(fk_anon(proto, cap_clause), decl, (*body),
+      expr_fn(proto, decl, ref body) => {
+        (v.visit_fn)(fk_anon(proto), decl, (*body),
                      ex.span, ex.id, e, v);
       }
-      expr_fn_block(decl, ref body, cap_clause) => {
-        (v.visit_fn)(fk_fn_block(cap_clause), decl, (*body),
+      expr_fn_block(decl, ref body) => {
+        (v.visit_fn)(fk_fn_block, decl, (*body),
                      ex.span, ex.id, e, v);
       }
       expr_block(ref b) => (v.visit_block)((*b), e, v),
@@ -471,7 +471,6 @@ pub fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
         (v.visit_expr)(a, e, v);
       }
       expr_copy(a) => (v.visit_expr)(a, e, v),
-      expr_unary_move(a) => (v.visit_expr)(a, e, v),
       expr_swap(a, b) => { (v.visit_expr)(a, e, v); (v.visit_expr)(b, e, v); }
       expr_assign_op(_, a, b) => {
         (v.visit_expr)(b, e, v);