diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 579699c9958..8aef8a0caee 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -640,40 +640,12 @@ enum stmt_ { stmt_semi(@expr, node_id), } -#[auto_serialize] -#[auto_deserialize] -enum init_op { init_assign, init_move, } - -impl init_op : cmp::Eq { - pure fn eq(other: &init_op) -> bool { - match self { - init_assign => { - match (*other) { - init_assign => true, - _ => false - } - } - init_move => { - match (*other) { - init_move => true, - _ => false - } - } - } - } - pure fn ne(other: &init_op) -> bool { !self.eq(other) } -} - -#[auto_serialize] -#[auto_deserialize] -type initializer = {op: init_op, expr: @expr}; - // FIXME (pending discussion of #1697, #2178...): local should really be // a refinement on pat. #[auto_serialize] #[auto_deserialize] type local_ = {is_mutbl: bool, ty: @Ty, pat: @pat, - init: Option, id: node_id}; + init: Option<@expr>, id: node_id}; type local = spanned; @@ -749,7 +721,6 @@ enum expr_ { expr_block(blk), expr_copy(@expr), - expr_move(@expr, @expr), expr_unary_move(@expr), expr_assign(@expr, @expr), expr_swap(@expr, @expr), diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 7eb7b2853e3..2fd1d8ec928 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -460,9 +460,6 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ { ..**cap_item})}))) } expr_block(blk) => expr_block(fld.fold_block(blk)), - expr_move(el, er) => { - 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) => { @@ -610,14 +607,7 @@ fn noop_fold_local(l: local_, fld: ast_fold) -> local_ { return {is_mutbl: l.is_mutbl, ty: fld.fold_ty(l.ty), pat: fld.fold_pat(l.pat), - init: - match l.init { - option::None:: => l.init, - option::Some::(init) => { - option::Some::({op: init.op, - expr: fld.fold_expr(init.expr)}) - } - }, + init: l.init.map(|e| fld.fold_expr(*e)), id: fld.new_id(l.id)}; } diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs index 4838c91f856..ff3abb5379e 100644 --- a/src/libsyntax/parse/classify.rs +++ b/src/libsyntax/parse/classify.rs @@ -43,7 +43,6 @@ fn need_parens(expr: @ast::expr, outer_prec: uint) -> bool { ast::expr_cast(_, _) => parse::prec::as_prec < outer_prec, // This may be too conservative in some cases ast::expr_assign(_, _) => true, - ast::expr_move(_, _) => true, ast::expr_swap(_, _) => true, ast::expr_assign_op(_, _, _) => true, ast::expr_ret(_) => true, @@ -61,8 +60,7 @@ fn ends_in_lit_int(ex: @ast::expr) -> bool { _ => false }, ast::expr_binary(_, _, sub) | ast::expr_unary(_, sub) | - ast::expr_move(_, sub) | ast::expr_copy(sub) | - ast::expr_assign(_, sub) | + ast::expr_copy(sub) | ast::expr_assign(_, sub) | ast::expr_assign_op(_, _, sub) | ast::expr_swap(_, sub) | ast::expr_log(_, _, sub) | ast::expr_assert(sub) => { ends_in_lit_int(sub) diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 1f607d849d9..1344c9b11ea 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -25,6 +25,8 @@ pub enum ObsoleteSyntax { ObsoleteModeInFnType, ObsoleteByMutRefMode, ObsoleteFixedLengthVec, + ObsoleteMoveInit, + ObsoleteBinaryMove } impl ObsoleteSyntax : cmp::Eq { @@ -104,6 +106,14 @@ impl Parser : ObsoleteReporter { "fixed-length vector", "Fixed-length types are now written `[T * N]`, and instances \ are type-inferred" + ), + ObsoleteMoveInit => ( + "initializer-by-move", + "Write `let foo = move bar` instead" + ), + ObsoleteBinaryMove => ( + "binary move", + "Write `foo = move bar` instead" ) }; diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 672f86b7a10..6e16e4eec1a 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -20,7 +20,8 @@ use obsolete::{ ObsoleteLowerCaseKindBounds, ObsoleteLet, ObsoleteFieldTerminator, ObsoleteStructCtor, ObsoleteWith, ObsoleteClassMethod, ObsoleteClassTraits, - ObsoleteModeInFnType, ObsoleteByMutRefMode + ObsoleteModeInFnType, ObsoleteByMutRefMode, + ObsoleteMoveInit, ObsoleteBinaryMove, }; use ast::{_mod, add, arg, arm, attribute, bind_by_ref, bind_by_implicit_ref, bind_by_value, bind_by_move, @@ -35,11 +36,11 @@ use ast::{_mod, add, arg, arm, attribute, expr_call, expr_cast, expr_copy, expr_do_body, expr_fail, expr_field, expr_fn, expr_fn_block, expr_if, expr_index, expr_lit, expr_log, expr_loop, expr_loop_body, expr_mac, - expr_move, expr_path, expr_rec, expr_repeat, expr_ret, expr_swap, + expr_path, expr_rec, expr_repeat, expr_ret, expr_swap, expr_struct, expr_tup, expr_unary, expr_unary_move, expr_vec, expr_vstore, expr_while, extern_fn, field, fn_decl, foreign_item, foreign_item_const, foreign_item_fn, foreign_mod, ident, - impure_fn, infer, inherited, init_assign, init_move, initializer, + impure_fn, infer, inherited, 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, @@ -1473,9 +1474,13 @@ impl Parser { expr_assign_op(aop, lhs, rhs)); } token::LARROW => { - self.bump(); - let rhs = self.parse_expr(); - return self.mk_expr(lo, rhs.span.hi, expr_move(lhs, rhs)); + self.obsolete(copy self.span, ObsoleteBinaryMove); + // Bogus value (but it's an error) + self.bump(); // <- + self.bump(); // rhs + self.bump(); // ; + return self.mk_expr(lo, self.span.hi, + expr_break(None)); } token::DARROW => { self.bump(); @@ -1745,23 +1750,18 @@ impl Parser { return e; } - fn parse_initializer() -> Option { + fn parse_initializer() -> Option<@expr> { match self.token { token::EQ => { self.bump(); - return Some({op: init_assign, expr: self.parse_expr()}); + return Some(self.parse_expr()); } token::LARROW => { - self.bump(); - return Some({op: init_move, expr: self.parse_expr()}); + self.obsolete(copy self.span, ObsoleteMoveInit); + self.bump(); + self.bump(); + return None; } - // Now that the the channel is the first argument to receive, - // combining it with an initializer doesn't really make sense. - // case (token::RECV) { - // self.bump(); - // return Some(rec(op = init_recv, - // expr = self.parse_expr())); - // } _ => { return None; } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index d68b28c6836..4a5e85c9eb6 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1310,18 +1310,13 @@ fn print_expr(s: ps, &&expr: @ast::expr) { print_block(s, blk); } ast::expr_copy(e) => { word_space(s, ~"copy"); print_expr(s, e); } + // shouldn't parenthesize unless it's needed ast::expr_unary_move(e) => { popen(s); word_space(s, ~"move"); print_expr(s, e); pclose(s); } - ast::expr_move(lhs, rhs) => { - print_expr(s, lhs); - space(s.s); - word_space(s, ~"<-"); - print_expr(s, rhs); - } ast::expr_assign(lhs, rhs) => { print_expr(s, lhs); space(s.s); @@ -1416,8 +1411,7 @@ fn print_expr_parens_if_not_bot(s: ps, ex: @ast::expr) { let parens = match ex.node { ast::expr_fail(_) | ast::expr_ret(_) | ast::expr_binary(_, _, _) | ast::expr_unary(_, _) | - ast::expr_move(_, _) | ast::expr_copy(_) | - ast::expr_assign(_, _) | + ast::expr_copy(_) | ast::expr_assign(_, _) | ast::expr_assign_op(_, _, _) | ast::expr_swap(_, _) | ast::expr_log(_, _, _) | ast::expr_assert(_) | ast::expr_call(_, _, true) | @@ -1458,11 +1452,8 @@ fn print_decl(s: ps, decl: @ast::decl) { match loc.node.init { Some(init) => { nbsp(s); - match init.op { - ast::init_assign => word_space(s, ~"="), - ast::init_move => word_space(s, ~"<-") - } - print_expr(s, init.expr); + word_space(s, ~"="); + print_expr(s, init); } _ => () } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 7035400f92d..e4eabfabf2f 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -116,7 +116,7 @@ fn visit_local(loc: @local, e: E, v: vt) { v.visit_ty(loc.node.ty, e, v); match loc.node.init { None => (), - Some(i) => v.visit_expr(i.expr, e, v) + Some(ex) => v.visit_expr(ex, e, v) } } @@ -442,7 +442,6 @@ fn visit_expr(ex: @expr, e: E, v: vt) { 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) => { v.visit_expr(b, e, v); diff --git a/src/rustc/middle/borrowck/check_loans.rs b/src/rustc/middle/borrowck/check_loans.rs index 7f95d44fd3b..efde1985677 100644 --- a/src/rustc/middle/borrowck/check_loans.rs +++ b/src/rustc/middle/borrowck/check_loans.rs @@ -583,12 +583,6 @@ fn check_loans_in_fn(fk: visit::fn_kind, decl: ast::fn_decl, body: ast::blk, fn check_loans_in_local(local: @ast::local, &&self: check_loan_ctxt, vt: visit::vt) { - match local.node.init { - Some({op: ast::init_move, expr: expr}) => { - self.check_move_out(expr); - } - Some({op: ast::init_assign, _}) | None => {} - } visit::visit_local(local, self, vt); } @@ -609,10 +603,6 @@ fn check_loans_in_expr(expr: @ast::expr, self.check_assignment(at_swap, l); self.check_assignment(at_swap, r); } - ast::expr_move(dest, src) => { - self.check_assignment(at_straight_up, dest); - self.check_move_out(src); - } ast::expr_unary_move(src) => { self.check_move_out(src); } diff --git a/src/rustc/middle/kind.rs b/src/rustc/middle/kind.rs index fdc8fc7ea8e..f8eee89f18a 100644 --- a/src/rustc/middle/kind.rs +++ b/src/rustc/middle/kind.rs @@ -374,7 +374,7 @@ fn check_stmt(stmt: @stmt, cx: ctx, v: visit::vt) { stmt_decl(@{node: decl_local(locals), _}, _) => { for locals.each |local| { match local.node.init { - Some({op: init_assign, expr}) => + Some(expr) => maybe_copy(cx, expr, Some(("initializer statement \ takes its right-hand side by copy", ""))), _ => {} diff --git a/src/rustc/middle/liveness.rs b/src/rustc/middle/liveness.rs index da3e7b175d0..c438474130f 100644 --- a/src/rustc/middle/liveness.rs +++ b/src/rustc/middle/liveness.rs @@ -552,7 +552,7 @@ fn visit_expr(expr: @expr, &&self: @IrMaps, vt: vt<@IrMaps>) { 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_unary_move(*) | expr_assign(*) | + expr_block(*) | expr_unary_move(*) | expr_assign(*) | expr_swap(*) | expr_assign_op(*) | expr_mac(*) | expr_struct(*) | expr_repeat(*) => { visit::visit_expr(expr, self, vt); @@ -1004,8 +1004,7 @@ impl Liveness { // initialization, which is mildly more complex than checking // once at the func header but otherwise equivalent. - let opt_init = local.node.init.map(|i| i.expr ); - let succ = self.propagate_through_opt_expr(opt_init, succ); + let succ = self.propagate_through_opt_expr(local.node.init, succ); self.define_bindings_in_pat(local.node.pat, succ) } @@ -1157,7 +1156,7 @@ impl Liveness { } } - expr_move(l, r) | expr_assign(l, r) => { + expr_assign(l, r) => { // see comment on lvalues in // propagate_through_lvalue_components() let succ = self.write_lvalue(l, succ, ACC_WRITE); @@ -1436,14 +1435,9 @@ impl Liveness { fn check_local(local: @local, &&self: @Liveness, vt: vt<@Liveness>) { match local.node.init { - Some({op: op, expr: expr}) => { + Some(_) => { // Initializer: - - match op { - init_move => self.check_move_from_expr(expr, vt), - init_assign => () - } self.warn_about_unused_or_dead_vars_in_pat(local.node.pat); if !local.node.is_mutbl { self.check_for_reassignments_in_pat(local.node.pat); @@ -1511,13 +1505,6 @@ fn check_expr(expr: @expr, &&self: @Liveness, vt: vt<@Liveness>) { visit::visit_expr(expr, self, vt); } - expr_move(l, r) => { - self.check_lvalue(l, vt); - self.check_move_from_expr(r, vt); - - visit::visit_expr(expr, self, vt); - } - expr_unary_move(r) => { self.check_move_from_expr(r, vt); diff --git a/src/rustc/middle/mem_categorization.rs b/src/rustc/middle/mem_categorization.rs index a61cb28c16b..e82892f3d1c 100644 --- a/src/rustc/middle/mem_categorization.rs +++ b/src/rustc/middle/mem_categorization.rs @@ -482,7 +482,7 @@ impl &mem_categorization_ctxt { } ast::expr_addr_of(*) | ast::expr_call(*) | - ast::expr_swap(*) | ast::expr_move(*) | ast::expr_assign(*) | + ast::expr_swap(*) | ast::expr_assign(*) | ast::expr_assign_op(*) | ast::expr_fn(*) | ast::expr_fn_block(*) | ast::expr_assert(*) | ast::expr_ret(*) | ast::expr_loop_body(*) | ast::expr_do_body(*) | ast::expr_unary(*) | diff --git a/src/rustc/middle/resolve.rs b/src/rustc/middle/resolve.rs index 73720648798..efddd6f4471 100644 --- a/src/rustc/middle/resolve.rs +++ b/src/rustc/middle/resolve.rs @@ -3982,7 +3982,7 @@ impl Resolver { // Nothing to do. } Some(initializer) => { - self.resolve_expr(initializer.expr, visitor); + self.resolve_expr(initializer, visitor); } } diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 61d4e6379a2..ae69904e219 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -960,7 +960,7 @@ fn init_local(bcx: block, local: @ast::local) -> block { // Handle let _ = e; just like e; match local.node.init { Some(init) => { - return expr::trans_into(bcx, init.expr, expr::Ignore); + return expr::trans_into(bcx, init, expr::Ignore); } None => { return bcx; } } @@ -977,12 +977,7 @@ fn init_local(bcx: block, local: @ast::local) -> block { let mut bcx = bcx; match local.node.init { Some(init) => { - if init.op == ast::init_assign || !bcx.expr_is_lval(init.expr) { - bcx = expr::trans_into(bcx, init.expr, expr::SaveIn(llptr)); - } else { // This is a move from an lval, perform an actual move - let init_datumblock = expr::trans_to_datum(bcx, init.expr); - bcx = init_datumblock.move_to(datum::INIT, llptr); - } + bcx = expr::trans_into(bcx, init, expr::SaveIn(llptr)); } _ => { zero_mem(bcx, llptr, ty); diff --git a/src/rustc/middle/trans/expr.rs b/src/rustc/middle/trans/expr.rs index b0702c80b39..a64aac3426a 100644 --- a/src/rustc/middle/trans/expr.rs +++ b/src/rustc/middle/trans/expr.rs @@ -438,11 +438,6 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { let dst_datum = unpack_datum!(bcx, trans_lvalue(bcx, dst)); return src_datum.store_to_datum(bcx, DROP_EXISTING, dst_datum); } - ast::expr_move(dst, src) => { - let src_datum = unpack_datum!(bcx, trans_to_datum(bcx, src)); - let dst_datum = unpack_datum!(bcx, trans_lvalue(bcx, dst)); - return src_datum.move_to_datum(bcx, DROP_EXISTING, dst_datum); - } ast::expr_swap(dst, src) => { let dst_datum = unpack_datum!(bcx, trans_lvalue(bcx, dst)); let src_datum = unpack_datum!(bcx, trans_lvalue(bcx, src)); diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs index ddd50d47c08..78fbb7f47be 100644 --- a/src/rustc/middle/trans/type_use.rs +++ b/src/rustc/middle/trans/type_use.rs @@ -180,8 +180,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_unary_move(_) | - expr_repeat(*) => { + expr_copy(_) | expr_unary_move(_) | expr_repeat(*) => { node_type_needs(cx, use_repr, e.id); } expr_cast(base, _) => { diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index 03e75957a92..68d82e4b74b 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -3018,7 +3018,6 @@ fn expr_kind(tcx: ctxt, ast::expr_while(*) | ast::expr_loop(*) | ast::expr_assign(*) | - ast::expr_move(*) | ast::expr_swap(*) | ast::expr_assign_op(*) => { RvalueStmtExpr diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs index 0641dc3bd7c..e95d92efc93 100644 --- a/src/rustc/middle/typeck/check.rs +++ b/src/rustc/middle/typeck/check.rs @@ -755,7 +755,7 @@ impl @fn_ctxt { fn with_region_lb(lb: ast::node_id, f: fn() -> R) -> R { let old_region_lb = self.region_lb; self.region_lb = lb; - let v <- f(); + let v = f(); self.region_lb = old_region_lb; move v } @@ -1776,9 +1776,6 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, bot = check_expr(fcx, a, expected); fcx.write_ty(id, fcx.expr_ty(a)); } - ast::expr_move(lhs, rhs) => { - bot = check_assignment(fcx, expr.span, lhs, rhs, id); - } ast::expr_assign(lhs, rhs) => { bot = check_assignment(fcx, expr.span, lhs, rhs, id); } @@ -2112,9 +2109,9 @@ fn require_integral(fcx: @fn_ctxt, sp: span, t: ty::t) { } fn check_decl_initializer(fcx: @fn_ctxt, nid: ast::node_id, - init: ast::initializer) -> bool { - let lty = ty::mk_var(fcx.ccx.tcx, lookup_local(fcx, init.expr.span, nid)); - return check_expr_with(fcx, init.expr, lty); + init: @ast::expr) -> bool { + let lty = ty::mk_var(fcx.ccx.tcx, lookup_local(fcx, init.span, nid)); + return check_expr_with(fcx, init, lty); } fn check_decl_local(fcx: @fn_ctxt, local: @ast::local) -> bool { @@ -2128,7 +2125,7 @@ fn check_decl_local(fcx: @fn_ctxt, local: @ast::local) -> bool { match local.node.init { Some(init) => { bot = check_decl_initializer(fcx, local.node.id, init); - is_lvalue = ty::expr_is_lval(tcx, fcx.ccx.method_map, init.expr); + is_lvalue = ty::expr_is_lval(tcx, fcx.ccx.method_map, init); } _ => { is_lvalue = true; diff --git a/src/rustc/middle/typeck/check/regionck.rs b/src/rustc/middle/typeck/check/regionck.rs index 932cdd994da..a38b805c7b4 100644 --- a/src/rustc/middle/typeck/check/regionck.rs +++ b/src/rustc/middle/typeck/check/regionck.rs @@ -147,7 +147,7 @@ fn visit_local(l: @ast::local, &&rcx: @rcx, v: rvt) { v.visit_ty(l.node.ty, rcx, v); for l.node.init.each |i| { - v.visit_expr(i.expr, rcx, v); + v.visit_expr(*i, rcx, v); } } diff --git a/src/rustc/util/common.rs b/src/rustc/util/common.rs index 0448b022602..36a63e3a106 100644 --- a/src/rustc/util/common.rs +++ b/src/rustc/util/common.rs @@ -8,7 +8,7 @@ fn indent(op: fn() -> R) -> R { // Use in conjunction with the log post-processor like `src/etc/indenter` // to make debug output more readable. debug!(">>"); - let r <- op(); + let r = op(); debug!("<< (Result = %?)", r); move r } @@ -75,7 +75,7 @@ fn block_query(b: ast::blk, p: fn@(@ast::expr) -> bool) -> bool { fn local_rhs_span(l: @ast::local, def: span) -> span { match l.node.init { - Some(i) => return i.expr.span, + Some(i) => return i.span, _ => return def } }