about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-07-31 17:31:24 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-07-31 17:33:20 -0700
commitc88933d714f12be6bdca80cc9583a1e5670cfc62 (patch)
tree8d17f1dc5cec7892ff7cc71bb4b5cf0d3a883f1b
parentc4bb8f8aafd25b9d5e68481af7088ab9e47c1e29 (diff)
downloadrust-c88933d714f12be6bdca80cc9583a1e5670cfc62.tar.gz
rust-c88933d714f12be6bdca80cc9583a1e5670cfc62.zip
rustc: Implement unary move. Closes #917.
-rw-r--r--src/etc/vim/syntax/rust.vim2
-rw-r--r--src/libcore/future.rs4
-rw-r--r--src/libcore/pipes.rs16
-rw-r--r--src/libsyntax/ast.rs1
-rw-r--r--src/libsyntax/fold.rs1
-rw-r--r--src/libsyntax/parse/parser.rs16
-rw-r--r--src/libsyntax/parse/token.rs2
-rw-r--r--src/libsyntax/print/pprust.rs1
-rw-r--r--src/libsyntax/visit.rs1
-rw-r--r--src/rustc/middle/borrowck/categorization.rs3
-rw-r--r--src/rustc/middle/liveness.rs11
-rw-r--r--src/rustc/middle/trans/base.rs2
-rw-r--r--src/rustc/middle/trans/type_use.rs2
-rw-r--r--src/rustc/middle/typeck/check.rs2
-rw-r--r--src/test/compile-fail/unary-move.rs8
15 files changed, 48 insertions, 24 deletions
diff --git a/src/etc/vim/syntax/rust.vim b/src/etc/vim/syntax/rust.vim
index b9fae069708..172de551ad0 100644
--- a/src/etc/vim/syntax/rust.vim
+++ b/src/etc/vim/syntax/rust.vim
@@ -15,7 +15,7 @@ syn match     rustAssert      "assert\(\w\)*"
 syn keyword   rustKeyword     alt again as break
 syn keyword   rustKeyword     check claim const copy do drop else export extern fail
 syn keyword   rustKeyword     for if impl import in let log
-syn keyword   rustKeyword     loop mod mut new of owned pure
+syn keyword   rustKeyword     loop mod move mut new of owned pure
 syn keyword   rustKeyword     ret self to unchecked
 syn match     rustKeyword     "unsafe" " Allows also matching unsafe::foo()
 syn keyword   rustKeyword     use while with
diff --git a/src/libcore/future.rs b/src/libcore/future.rs
index 7dfafd499a4..43b0a4047b6 100644
--- a/src/libcore/future.rs
+++ b/src/libcore/future.rs
@@ -60,7 +60,7 @@ fn from_value<A>(+val: A) -> future<A> {
     })
 }
 
-macro_rules! move{
+macro_rules! move_it {
     {$x:expr} => { unsafe { let y <- *ptr::addr_of($x); y } }
 }
 
@@ -78,7 +78,7 @@ fn from_port<A:send>(-port: future_pipe::client::waiting<A>) -> future<A> {
         port_ <-> *port;
         let port = option::unwrap(port_);
         alt recv(port) {
-          future_pipe::completed(data) { move!{data} }
+          future_pipe::completed(data) { move_it!{data} }
         }
     }
 }
diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs
index 873ffd05aa5..3d115463844 100644
--- a/src/libcore/pipes.rs
+++ b/src/libcore/pipes.rs
@@ -22,13 +22,13 @@ export stream, port, chan, shared_chan, port_set, channel;
 
 const SPIN_COUNT: uint = 0;
 
-macro_rules! move {
+macro_rules! move_it {
     { $x:expr } => { unsafe { let y <- *ptr::addr_of($x); y } }
 }
 
 // This is to help make sure we only move out of enums in safe
 // places. Once there is unary move, it can be removed.
-fn move<T>(-x: T) -> T { x }
+fn move_it<T>(-x: T) -> T { x }
 
 enum state {
     empty,
@@ -228,7 +228,7 @@ class buffer_resource<T: send> {
     }
 
     drop unsafe {
-        let b = move!{self.buffer};
+        let b = move_it!{self.buffer};
         //let p = ptr::addr_of(*b);
         //error!{"drop %?", p};
         let old_count = atomic_sub_rel(b.header.ref_count, 1);
@@ -725,10 +725,10 @@ impl port<T: send> of recv<T> for port<T> {
     fn try_recv() -> option<T> {
         let mut endp = none;
         endp <-> self.endp;
-        alt move(pipes::try_recv(unwrap(endp))) {
+        alt move_it(pipes::try_recv(unwrap(endp))) {
           some(streamp::data(x, endp)) {
-            self.endp = some(move!{endp});
-            some(move!{x})
+            self.endp = some(move_it!{endp});
+            some(move_it!{x})
           }
           none { none }
         }
@@ -770,9 +770,9 @@ class port_set<T: send> : recv<T> {
             let i = wait_many(self.ports.map(|p| p.header()));
             // dereferencing an unsafe pointer nonsense to appease the
             // borrowchecker.
-            alt move(unsafe {(*ptr::addr_of(self.ports[i])).try_recv()}) {
+            alt move_it(unsafe {(*ptr::addr_of(self.ports[i])).try_recv()}) {
               some(m) {
-                  result = some(move!{m});
+                  result = some(move_it!{m});
               }
               none {
                 // Remove this port.
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 6e56e5ca65a..8c2b6dc3490 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -322,6 +322,7 @@ enum expr_ {
 
     expr_copy(@expr),
     expr_move(@expr, @expr),
+    expr_unary_move(@expr),
     expr_assign(@expr, @expr),
     expr_swap(@expr, @expr),
     expr_assign_op(binop, @expr, @expr),
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index dd051564cf4..5e533f3f494 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -454,6 +454,7 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
             expr_move(fld.fold_expr(el), fld.fold_expr(er))
           }
           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 28ad7173be8..aaafbf0ef24 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -31,12 +31,12 @@ import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
              expr_index, expr_lit, expr_log, expr_loop,
              expr_loop_body, expr_mac, expr_move, expr_new, expr_path,
              expr_rec, expr_ret, expr_swap, expr_struct, expr_tup, expr_unary,
-             expr_vec, expr_vstore, expr_while, extern_fn, field, fn_decl,
-             foreign_item, foreign_item_fn, foreign_mod, ident, impure_fn,
-             infer, init_assign, init_move, initializer, instance_var, item,
-             item_, item_class, item_const, item_enum, item_fn,
-             item_foreign_mod, item_impl, item_mac, item_mod, item_trait,
-             item_ty, lit, lit_, lit_bool, lit_float, lit_int,
+             expr_unary_move, expr_vec, expr_vstore, expr_while, extern_fn,
+             field, fn_decl, foreign_item, foreign_item_fn, foreign_mod,
+             ident, impure_fn, infer, init_assign, init_move, initializer,
+             instance_var, item, item_, item_class, item_const, item_enum,
+             item_fn, item_foreign_mod, item_impl, item_mac, item_mod,
+             item_trait, item_ty, lit, lit_, lit_bool, lit_float, lit_int,
              lit_int_unsuffixed, lit_nil, lit_str, lit_uint, local, m_const,
              m_imm, m_mutbl, mac_, mac_aq, mac_ellipsis,
              mac_invoc, mac_invoc_tt, mac_var, matcher, match_nonterminal,
@@ -854,6 +854,10 @@ class parser {
             let e = self.parse_expr();
             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;
         } else if self.token == token::MOD_SEP ||
             is_ident(self.token) && !self.is_keyword(~"true") &&
             !self.is_keyword(~"false") {
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index e4386ab140f..1d4e67c5d14 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -327,7 +327,7 @@ fn restricted_keyword_table() -> hashmap<~str, ()> {
         ~"fail", ~"false", ~"fn", ~"for",
         ~"if", ~"iface", ~"impl", ~"import",
         ~"let", ~"log", ~"loop",
-        ~"match", ~"mod", ~"module", ~"mut",
+        ~"match", ~"mod", ~"module", ~"move", ~"mut",
         ~"new",
         ~"owned",
         ~"pure",
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 3292831c32f..41e795fd436 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1100,6 +1100,7 @@ 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_move(lhs, rhs) {
         print_expr(s, lhs);
         space(s.s);
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index a542ca574ac..050d7e58120 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -408,6 +408,7 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
       expr_block(b) { v.visit_block(b, e, v); }
       expr_assign(a, b) { v.visit_expr(b, e, v); 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_move(a, b) { v.visit_expr(b, e, v); 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) {
diff --git a/src/rustc/middle/borrowck/categorization.rs b/src/rustc/middle/borrowck/categorization.rs
index 6f5b5d139d3..36b35dbbdbc 100644
--- a/src/rustc/middle/borrowck/categorization.rs
+++ b/src/rustc/middle/borrowck/categorization.rs
@@ -181,7 +181,8 @@ impl public_methods for borrowck_ctxt {
           ast::expr_new(*) | ast::expr_binary(*) | ast::expr_while(*) |
           ast::expr_block(*) | ast::expr_loop(*) | ast::expr_alt(*) |
           ast::expr_lit(*) | ast::expr_break | ast::expr_mac(*) |
-          ast::expr_again | ast::expr_rec(*) | ast::expr_struct(*) {
+          ast::expr_again | ast::expr_rec(*) | ast::expr_struct(*) |
+          ast::expr_unary_move(*) {
             ret self.cat_rvalue(expr, expr_ty);
           }
         }
diff --git a/src/rustc/middle/liveness.rs b/src/rustc/middle/liveness.rs
index e7d88b9b2b8..8a65a1b0567 100644
--- a/src/rustc/middle/liveness.rs
+++ b/src/rustc/middle/liveness.rs
@@ -470,8 +470,8 @@ fn visit_expr(expr: @expr, &&self: @ir_maps, vt: vt<@ir_maps>) {
       expr_loop_body(*) | expr_do_body(*) | expr_cast(*) |
       expr_unary(*) | expr_fail(*) |
       expr_break | expr_again | expr_lit(_) | expr_ret(*) |
-      expr_block(*) | expr_move(*) | expr_assign(*) | expr_swap(*) |
-      expr_assign_op(*) | expr_mac(*) | expr_struct(*) {
+      expr_block(*) | expr_move(*) | expr_unary_move(*) | expr_assign(*) |
+      expr_swap(*) | expr_assign_op(*) | expr_mac(*) | expr_struct(*) => {
           visit::visit_expr(expr, self, vt);
       }
     }
@@ -1104,6 +1104,7 @@ class liveness {
           expr_assert(e) |
           expr_addr_of(_, e) |
           expr_copy(e) |
+          expr_unary_move(e) |
           expr_loop_body(e) |
           expr_do_body(e) |
           expr_cast(e, _) |
@@ -1430,6 +1431,12 @@ fn check_expr(expr: @expr, &&self: @liveness, vt: vt<@liveness>) {
         visit::visit_expr(expr, self, vt);
       }
 
+      expr_unary_move(r) {
+        self.check_move_from_expr(r, vt);
+
+        visit::visit_expr(expr, self, vt);
+      }
+
       expr_assign_op(_, l, _) {
         self.check_lvalue(l, vt);
 
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index 2e5d5051a79..96e7c74f25d 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -3682,7 +3682,7 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block {
           ast::expr_do_body(blk) {
             ret trans_expr(bcx, blk, dest);
           }
-          ast::expr_copy(a) {
+          ast::expr_copy(a) | ast::expr_unary_move(a) {
             if !expr_is_lval(bcx, a) {
                 ret trans_expr(bcx, a, dest);
             }
diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs
index 6bb19724afe..8ab6fbfc6eb 100644
--- a/src/rustc/middle/trans/type_use.rs
+++ b/src/rustc/middle/trans/type_use.rs
@@ -158,7 +158,7 @@ fn mark_for_expr(cx: ctx, e: @expr) {
       expr_rec(_, _) | expr_struct(*) | expr_tup(_) |
       expr_unary(box(_), _) | expr_unary(uniq(_), _) |
       expr_binary(add, _, _) |
-      expr_copy(_) | expr_move(_, _) {
+      expr_copy(_) | expr_move(_, _) | expr_unary_move(_) {
         node_type_needs(cx, use_repr, e.id);
       }
       expr_cast(base, _) {
diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs
index 1f589a1b960..db9084cbad1 100644
--- a/src/rustc/middle/typeck/check.rs
+++ b/src/rustc/middle/typeck/check.rs
@@ -1416,7 +1416,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
         bot = check_expr_with(fcx, e, ty::mk_bool(tcx));
         fcx.write_nil(id);
       }
-      ast::expr_copy(a) {
+      ast::expr_copy(a) | ast::expr_unary_move(a) {
         bot = check_expr(fcx, a, expected);
         fcx.write_ty(id, fcx.expr_ty(a));
       }
diff --git a/src/test/compile-fail/unary-move.rs b/src/test/compile-fail/unary-move.rs
new file mode 100644
index 00000000000..5178d5a1e9b
--- /dev/null
+++ b/src/test/compile-fail/unary-move.rs
@@ -0,0 +1,8 @@
+// error-pattern: use of moved variable
+
+fn main() {
+    let x = 3;
+    let y = move x;
+    debug!("%d", x);
+}
+