From f64e52a7f703ecb18cbf7c39bd1479cd99bd20ae Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Mon, 1 Dec 2014 13:18:18 -0500 Subject: [PATCH] Tell trans which binops are by value --- src/librustc_trans/trans/callee.rs | 11 ++++++----- src/librustc_trans/trans/expr.rs | 23 ++++++++++++++--------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index b8b2395dde17..bde68981ff49 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -996,10 +996,11 @@ pub enum CallArgs<'a, 'tcx> { // value. ArgVals(&'a [ValueRef]), - // For overloaded operators: `(lhs, Vec(rhs, rhs_id))`. `lhs` + // For overloaded operators: `(lhs, Vec(rhs, rhs_id), autoref)`. `lhs` // is the left-hand-side and `rhs/rhs_id` is the datum/expr-id of - // the right-hand-side arguments (if any). - ArgOverloadedOp(Datum<'tcx, Expr>, Vec<(Datum<'tcx, Expr>, ast::NodeId)>), + // the right-hand-side arguments (if any). `autoref` indicates whether the `rhs` + // arguments should be auto-referenced + ArgOverloadedOp(Datum<'tcx, Expr>, Vec<(Datum<'tcx, Expr>, ast::NodeId)>, bool), // Supply value of arguments as a list of expressions that must be // translated, for overloaded call operators. @@ -1171,7 +1172,7 @@ pub fn trans_args<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>, arg_cleanup_scope, ignore_self) } - ArgOverloadedOp(lhs, rhs) => { + ArgOverloadedOp(lhs, rhs, autoref) => { assert!(!variadic); llargs.push(unpack_result!(bcx, { @@ -1185,7 +1186,7 @@ pub fn trans_args<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>, llargs.push(unpack_result!(bcx, { trans_arg_datum(bcx, arg_tys[1], rhs, arg_cleanup_scope, - DoAutorefArg(rhs_id)) + if autoref { DoAutorefArg(rhs_id) } else { DontAutorefArg }) })); } } diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index e1769001942d..55672004f142 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -609,7 +609,8 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, method_call, base_datum, args, - Some(SaveIn(scratch.val)))); + Some(SaveIn(scratch.val)), + true)); DatumBlock::new(bcx, scratch.to_expr_datum()) } ast::ExprBox(_, ref contents) => { @@ -762,7 +763,8 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, method_call, base_datum, vec![(ix_datum, idx.id)], - Some(SaveIn(scratch.val)))); + Some(SaveIn(scratch.val)), + true)); let datum = scratch.to_expr_datum(); if ty::type_is_sized(bcx.tcx(), elt_ty) { Datum::new(datum.to_llscalarish(bcx), elt_ty, LvalueExpr) @@ -1092,25 +1094,26 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, callee::ArgExprs(args.as_slice()), dest) } - ast::ExprBinary(_, ref lhs, ref rhs) => { + ast::ExprBinary(op, ref lhs, ref rhs) => { // if not overloaded, would be RvalueDatumExpr let lhs = unpack_datum!(bcx, trans(bcx, &**lhs)); let rhs_datum = unpack_datum!(bcx, trans(bcx, &**rhs)); trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), lhs, - vec![(rhs_datum, rhs.id)], Some(dest)).bcx + vec![(rhs_datum, rhs.id)], Some(dest), + !ast_util::is_by_value_binop(op)).bcx } ast::ExprUnary(_, ref subexpr) => { // if not overloaded, would be RvalueDatumExpr let arg = unpack_datum!(bcx, trans(bcx, &**subexpr)); trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), - arg, Vec::new(), Some(dest)).bcx + arg, Vec::new(), Some(dest), true).bcx } ast::ExprIndex(ref base, ref idx) => { // if not overloaded, would be RvalueDatumExpr let base = unpack_datum!(bcx, trans(bcx, &**base)); let idx_datum = unpack_datum!(bcx, trans(bcx, &**idx)); trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), base, - vec![(idx_datum, idx.id)], Some(dest)).bcx + vec![(idx_datum, idx.id)], Some(dest), true).bcx } ast::ExprCast(ref val, _) => { // DPS output mode means this is a trait cast: @@ -1803,7 +1806,8 @@ fn trans_overloaded_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, method_call: MethodCall, lhs: Datum<'tcx, Expr>, rhs: Vec<(Datum<'tcx, Expr>, ast::NodeId)>, - dest: Option) + dest: Option, + autoref: bool) -> Result<'blk, 'tcx> { let method_ty = (*bcx.tcx().method_map.borrow())[method_call].ty; callee::trans_call_inner(bcx, @@ -1815,7 +1819,7 @@ fn trans_overloaded_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, None, arg_cleanup_scope) }, - callee::ArgOverloadedOp(lhs, rhs), + callee::ArgOverloadedOp(lhs, rhs, autoref), dest) } @@ -2122,7 +2126,8 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let scratch = rvalue_scratch_datum(bcx, ref_ty, "overloaded_deref"); unpack_result!(bcx, trans_overloaded_op(bcx, expr, method_call, - datum, Vec::new(), Some(SaveIn(scratch.val)))); + datum, Vec::new(), Some(SaveIn(scratch.val)), + false)); scratch.to_expr_datum() } None => {