diff --git a/doc/rust.md b/doc/rust.md index ac7125be424..60848441e4e 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -1946,35 +1946,6 @@ fn avg(v: &[float]) -> float { } ~~~~ -#### Swap expressions - -A _swap expression_ consists of an [lvalue](#lvalues-rvalues-and-temporaries) followed by a bi-directional arrow (`<->`) and another [lvalue](#lvalues-rvalues-and-temporaries). - -Evaluating a swap expression causes, as a side effect, the values held in the left-hand-side and right-hand-side [lvalues](#lvalues-rvalues-and-temporaries) to be exchanged indivisibly. - -Evaluating a swap expression neither changes reference counts, -nor deeply copies any owned structure pointed to by the moved [rvalue](#lvalues-rvalues-and-temporaries). -Instead, the swap expression represents an indivisible *exchange of ownership*, -between the right-hand-side and the left-hand-side of the expression. -No allocation or destruction is entailed. - -An example of three different swap expressions: - -~~~~~~~~ -# let mut x = &mut [0]; -# let mut a = &mut [0]; -# let i = 0; -# struct S1 { z: int }; -# struct S2 { c: int }; -# let mut y = S1{z: 0}; -# let mut b = S2{c: 0}; - -x <-> a; -x[i] <-> a[i]; -y.z <-> b.c; -~~~~~~~~ - - #### Assignment expressions An _assignment expression_ consists of an [lvalue](#lvalues-rvalues-and-temporaries) expression followed by an @@ -2015,7 +1986,7 @@ as == != && || -= <-> += ~~~~ Operators at the same precedence level are evaluated left-to-right. diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 27f6ae33ba3..2f116cb1b28 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -758,10 +758,6 @@ fn check_loans_in_expr<'a>(expr: @ast::expr, } match expr.node { - ast::expr_swap(l, r) => { - self.check_assignment(l); - self.check_assignment(r); - } ast::expr_assign(dest, _) | ast::expr_assign_op(_, dest, _) => { self.check_assignment(dest); diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index f1fa5144f4c..dc08fb39ad9 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -698,11 +698,6 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { self.walk_expr(l, in_out, loop_scopes); } - ast::expr_swap(l, r) => { - self.walk_expr(l, in_out, loop_scopes); - self.walk_expr(r, in_out, loop_scopes); - } - ast::expr_vec(ref exprs, _) => { self.walk_exprs(*exprs, in_out, loop_scopes) } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 0bd73a15d50..52274f3d305 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -523,7 +523,7 @@ fn visit_expr(expr: @expr, self: @mut IrMaps, vt: vt<@mut IrMaps>) { expr_binary(*) | expr_addr_of(*) | expr_copy(*) | expr_loop_body(*) | expr_do_body(*) | expr_cast(*) | expr_unary(*) | expr_break(_) | expr_again(_) | expr_lit(_) | expr_ret(*) | expr_block(*) | - expr_assign(*) | expr_swap(*) | expr_assign_op(*) | expr_mac(*) | + expr_assign(*) | expr_assign_op(*) | expr_mac(*) | expr_struct(*) | expr_repeat(*) | expr_paren(*) | expr_inline_asm(*) => { visit::visit_expr(expr, self, vt); @@ -1141,21 +1141,6 @@ pub impl Liveness { self.propagate_through_expr(r, succ) } - expr_swap(l, r) => { - // see comment on lvalues in - // propagate_through_lvalue_components() - - // I count swaps as `used` cause it might be something like: - // foo.bar <-> x - // and I am too lazy to distinguish this case from - // y <-> x - // (where both x, y are unused) just for a warning. - let succ = self.write_lvalue(r, succ, ACC_WRITE|ACC_READ|ACC_USE); - let succ = self.write_lvalue(l, succ, ACC_WRITE|ACC_READ|ACC_USE); - let succ = self.propagate_through_lvalue_components(r, succ); - self.propagate_through_lvalue_components(l, succ) - } - expr_assign_op(_, l, r) => { // see comment on lvalues in // propagate_through_lvalue_components() @@ -1533,7 +1518,7 @@ fn check_expr(expr: @expr, self: @Liveness, vt: vt<@Liveness>) { expr_vstore(*) | expr_vec(*) | expr_tup(*) | expr_log(*) | expr_binary(*) | expr_copy(*) | expr_loop_body(*) | expr_do_body(*) | expr_cast(*) | expr_unary(*) | expr_ret(*) | expr_break(*) | - expr_again(*) | expr_lit(_) | expr_block(*) | expr_swap(*) | + expr_again(*) | expr_lit(_) | expr_block(*) | expr_mac(*) | expr_addr_of(*) | expr_struct(*) | expr_repeat(*) | expr_paren(*) => { visit::visit_expr(expr, self, vt); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 0e819c66f09..7675efa76f4 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -413,7 +413,7 @@ pub impl mem_categorization_ctxt { ast::expr_paren(e) => self.cat_expr_unadjusted(e), - ast::expr_addr_of(*) | ast::expr_call(*) | ast::expr_swap(*) | + ast::expr_addr_of(*) | ast::expr_call(*) | ast::expr_assign(*) | ast::expr_assign_op(*) | ast::expr_fn_block(*) | ast::expr_ret(*) | ast::expr_loop_body(*) | ast::expr_do_body(*) | ast::expr_unary(*) | diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index 040ff30f9e6..2471e383bca 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -650,11 +650,6 @@ pub impl VisitContext { self.consume_expr(count, visitor); } - expr_swap(lhs, rhs) => { - self.use_expr(lhs, Read, visitor); - self.use_expr(rhs, Read, visitor); - } - expr_loop_body(base) | expr_do_body(base) => { self.use_expr(base, comp_mode, visitor); diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 1b7cdf3ac80..ed3dfdc07c3 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -528,33 +528,6 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { return src_datum.store_to_datum( bcx, src.id, 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)); - - // If the source and destination are the same, then don't swap. - // Avoids performing an overlapping memcpy - let dst_datum_ref = dst_datum.to_ref_llval(bcx); - let src_datum_ref = src_datum.to_ref_llval(bcx); - let cmp = ICmp(bcx, lib::llvm::IntEQ, - src_datum_ref, - dst_datum_ref); - - let swap_cx = base::sub_block(bcx, "swap"); - let next_cx = base::sub_block(bcx, "next"); - - CondBr(bcx, cmp, next_cx.llbb, swap_cx.llbb); - - let scratch = scratch_datum(swap_cx, dst_datum.ty, false); - - let swap_cx = dst_datum.move_to_datum(swap_cx, INIT, scratch); - let swap_cx = src_datum.move_to_datum(swap_cx, INIT, dst_datum); - let swap_cx = scratch.move_to_datum(swap_cx, INIT, src_datum); - - Br(swap_cx, next_cx.llbb); - - return next_cx; - } ast::expr_assign_op(op, dst, src) => { return trans_assign_op(bcx, expr, op, dst, src); } diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index cbad7bcb3a6..3c2738d3ae8 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -314,7 +314,7 @@ pub fn mark_for_expr(cx: Context, e: @expr) { } } } - expr_assign(val, _) | expr_swap(val, _) | expr_assign_op(_, val, _) | + expr_assign(val, _) | expr_assign_op(_, val, _) | expr_ret(Some(val)) => { node_type_needs(cx, use_repr, val.id); } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 737548ee868..829a1e399de 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3465,7 +3465,6 @@ pub fn expr_kind(tcx: ctxt, ast::expr_while(*) | ast::expr_loop(*) | ast::expr_assign(*) | - ast::expr_swap(*) | ast::expr_inline_asm(*) | ast::expr_assign_op(*) => { RvalueStmtExpr diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index baa28b64982..7c79693a8b2 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -2460,20 +2460,6 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.write_nil(id); } } - ast::expr_swap(lhs, rhs) => { - check_assignment(fcx, lhs, rhs, id); - let lhs_ty = fcx.expr_ty(lhs); - let rhs_ty = fcx.expr_ty(rhs); - if ty::type_is_error(lhs_ty) || ty::type_is_error(rhs_ty) { - fcx.write_error(id); - } - else if ty::type_is_bot(lhs_ty) || ty::type_is_bot(rhs_ty) { - fcx.write_bot(id); - } - else { - fcx.write_nil(id); - } - } ast::expr_if(cond, ref thn, elsopt) => { check_expr_has_type(fcx, cond, ty::mk_bool()); check_then_else(fcx, thn, elsopt, id, expr.span); diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 2274259f18c..55c1f03b330 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -1016,7 +1016,6 @@ pub mod guarantor { ast::expr_while(*) | ast::expr_loop(*) | ast::expr_assign(*) | - ast::expr_swap(*) | ast::expr_assign_op(*) | ast::expr_cast(*) | ast::expr_call(*) | diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc index a8cd7f5f41c..836ca1cfa45 100644 --- a/src/librusti/rusti.rc +++ b/src/librusti/rusti.rc @@ -96,10 +96,6 @@ fn record(repl: Repl, blk: @ast::blk, intr: @token::ident_interner) -> Repl { match expr.node { ast::expr_assign(*) | ast::expr_assign_op(*) | - ast::expr_swap(*) => { - pprust::print_stmt(pp, *stmt); - writer.write_line(~""); - } _ => {} } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index f4e3e683229..8aa59fd1775 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -569,7 +569,6 @@ pub enum expr_ { expr_copy(@expr), expr_assign(@expr, @expr), - expr_swap(@expr, @expr), expr_assign_op(binop, @expr, @expr), expr_field(@expr, ident, ~[@Ty]), expr_index(@expr, @expr), diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index d181dd87e38..338b9b29f00 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -511,9 +511,6 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ { expr_assign(el, er) => { expr_assign(fld.fold_expr(el), fld.fold_expr(er)) } - expr_swap(el, er) => { - expr_swap(fld.fold_expr(el), fld.fold_expr(er)) - } expr_assign_op(op, el, er) => { expr_assign_op(op, fld.fold_expr(el), fld.fold_expr(er)) } diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index a4ac038cf46..e9e5bdfe13d 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -40,6 +40,7 @@ pub enum ObsoleteSyntax { ObsoleteModeInFnType, ObsoleteMoveInit, ObsoleteBinaryMove, + ObsoleteSwap, ObsoleteUnsafeBlock, ObsoleteUnenforcedBound, ObsoleteImplSyntax, @@ -129,6 +130,10 @@ pub impl Parser { "binary move", "Write `foo = move bar` instead" ), + ObsoleteSwap => ( + "swap", + "Use core::util::{swap, replace} instead" + ), ObsoleteUnsafeBlock => ( "non-standalone unsafe block", "use an inner `unsafe { ... }` block instead" diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 3ddc7a87924..5aa45ab3c9b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -26,7 +26,7 @@ use ast::{expr_break, expr_call, expr_cast, expr_copy, expr_do_body}; use ast::{expr_field, 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_repeat}; -use ast::{expr_ret, expr_swap, expr_struct, expr_tup, expr_unary}; +use ast::{expr_ret, expr_struct, expr_tup, expr_unary}; use ast::{expr_vec, expr_vstore, expr_vstore_mut_box}; use ast::{expr_vstore_slice, expr_vstore_box}; use ast::{expr_vstore_mut_slice, expr_while, extern_fn, field, fn_decl}; @@ -70,7 +70,7 @@ use parse::lexer::reader; use parse::lexer::TokenAndSpan; use parse::obsolete::{ObsoleteClassTraits}; use parse::obsolete::{ObsoleteLet, ObsoleteFieldTerminator}; -use parse::obsolete::{ObsoleteMoveInit, ObsoleteBinaryMove}; +use parse::obsolete::{ObsoleteMoveInit, ObsoleteBinaryMove, ObsoleteSwap}; use parse::obsolete::{ObsoleteSyntax, ObsoleteLowerCaseKindBounds}; use parse::obsolete::{ObsoleteUnsafeBlock, ObsoleteImplSyntax}; use parse::obsolete::{ObsoleteTraitBoundSeparator, ObsoleteMutOwnedPointer}; @@ -1849,9 +1849,11 @@ pub impl Parser { expr_break(None)) } token::DARROW => { + self.obsolete(*self.span, ObsoleteSwap); self.bump(); - let rhs = self.parse_expr(); - self.mk_expr(lo, rhs.span.hi, expr_swap(lhs, rhs)) + // Ignore what we get, this is an error anyway + self.parse_expr(); + self.mk_expr(lo, self.span.hi, expr_break(None)) } _ => { lhs diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 81652f9c1a1..9d2927eb74f 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1328,12 +1328,6 @@ pub fn print_expr(s: @ps, expr: @ast::expr) { word_space(s, ~"="); print_expr(s, rhs); } - ast::expr_swap(lhs, rhs) => { - print_expr(s, lhs); - space(s.s); - word_space(s, ~"<->"); - print_expr(s, rhs); - } ast::expr_assign_op(op, lhs, rhs) => { print_expr(s, lhs); space(s.s); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 90dd49d6848..dcc94c92a88 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -516,10 +516,6 @@ pub fn visit_expr(ex: @expr, e: E, v: vt) { (v.visit_expr)(a, e, v); } expr_copy(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); (v.visit_expr)(a, e, v);