Skip to content

Commit f4abb12

Browse files
author
Jorge Aparicio
committed
Address Niko's comments
1 parent d193bf3 commit f4abb12

File tree

2 files changed

+61
-50
lines changed

2 files changed

+61
-50
lines changed

src/librustc/middle/expr_use_visitor.rs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,12 @@ macro_rules! return_if_err(
329329
)
330330
)
331331

332+
/// Whether the elements of an overloaded operation are passed by value or by reference
333+
enum PassArgs {
334+
ByValue,
335+
ByRef,
336+
}
337+
332338
impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
333339
pub fn new(delegate: &'d mut Delegate<'tcx>,
334340
typer: &'t TYPER,
@@ -438,7 +444,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
438444
ast::ExprPath(..) => { }
439445

440446
ast::ExprUnary(ast::UnDeref, ref base) => { // *base
441-
if !self.walk_overloaded_operator(expr, &**base, Vec::new(), None) {
447+
if !self.walk_overloaded_operator(expr, &**base, Vec::new(), PassArgs::ByRef) {
442448
self.select_from_expr(&**base);
443449
}
444450
}
@@ -452,7 +458,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
452458
}
453459

454460
ast::ExprIndex(ref lhs, ref rhs) => { // lhs[rhs]
455-
if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs], None) {
461+
if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs], PassArgs::ByRef) {
456462
self.select_from_expr(&**lhs);
457463
self.consume_expr(&**rhs);
458464
}
@@ -465,7 +471,8 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
465471
(&None, &Some(ref e)) => vec![&**e],
466472
(&None, &None) => Vec::new()
467473
};
468-
let overloaded = self.walk_overloaded_operator(expr, &**base, args, None);
474+
let overloaded =
475+
self.walk_overloaded_operator(expr, &**base, args, PassArgs::ByRef);
469476
assert!(overloaded);
470477
}
471478

@@ -570,14 +577,19 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
570577
}
571578

572579
ast::ExprUnary(_, ref lhs) => {
573-
if !self.walk_overloaded_operator(expr, &**lhs, Vec::new(), None) {
580+
if !self.walk_overloaded_operator(expr, &**lhs, Vec::new(), PassArgs::ByRef) {
574581
self.consume_expr(&**lhs);
575582
}
576583
}
577584

578585
ast::ExprBinary(op, ref lhs, ref rhs) => {
579-
if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs], Some(op))
580-
{
586+
let pass_args = if ast_util::is_by_value_binop(op) {
587+
PassArgs::ByValue
588+
} else {
589+
PassArgs::ByRef
590+
};
591+
592+
if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs], pass_args) {
581593
self.consume_expr(&**lhs);
582594
self.consume_expr(&**rhs);
583595
}
@@ -913,21 +925,21 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
913925
expr: &ast::Expr,
914926
receiver: &ast::Expr,
915927
rhs: Vec<&ast::Expr>,
916-
binop: Option<ast::BinOp>)
928+
pass_args: PassArgs)
917929
-> bool
918930
{
919931
if !self.typer.is_method_call(expr.id) {
920932
return false;
921933
}
922934

923-
match binop {
924-
Some(binop) if ast_util::is_by_value_binop(binop) => {
935+
match pass_args {
936+
PassArgs::ByValue => {
925937
self.consume_expr(receiver);
926938
self.consume_expr(rhs[0]);
927939

928940
return true;
929941
},
930-
_ => {},
942+
PassArgs::ByRef => {},
931943
}
932944

933945
self.walk_expr(receiver);

src/librustc_typeck/check/mod.rs

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ type parameter).
7777
*/
7878

7979
pub use self::LvaluePreference::*;
80-
pub use self::DerefArgs::*;
8180
pub use self::Expectation::*;
8281
use self::IsBinopAssignment::*;
8382
use self::TupleArgumentsFlag::*;
@@ -2117,7 +2116,7 @@ fn try_overloaded_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
21172116
method_callee.ty,
21182117
call_expression,
21192118
args,
2120-
DontDerefArgs,
2119+
AutorefArgs::No,
21212120
TupleArguments);
21222121
fcx.inh.method_map.borrow_mut().insert(method_call, method_callee);
21232122
write_call(fcx, call_expression, output_type);
@@ -2274,7 +2273,7 @@ fn try_overloaded_slice<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
22742273
method_ty_or_err,
22752274
expr,
22762275
args.as_slice(),
2277-
DoDerefArgs,
2276+
AutorefArgs::Yes,
22782277
DontTupleArguments);
22792278

22802279
opt_method_ty.map(|method_ty| {
@@ -2480,7 +2479,7 @@ fn lookup_method_for_for_loop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
24802479
method_type,
24812480
iterator_expr,
24822481
&[],
2483-
DontDerefArgs,
2482+
AutorefArgs::No,
24842483
DontTupleArguments);
24852484

24862485
match method {
@@ -2522,7 +2521,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
25222521
method_fn_ty: Ty<'tcx>,
25232522
callee_expr: &ast::Expr,
25242523
args_no_rcvr: &[&P<ast::Expr>],
2525-
deref_args: DerefArgs,
2524+
autoref_args: AutorefArgs,
25262525
tuple_arguments: TupleArgumentsFlag)
25272526
-> ty::FnOutput<'tcx> {
25282527
if ty::type_is_error(method_fn_ty) {
@@ -2538,7 +2537,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
25382537
err_inputs.as_slice(),
25392538
callee_expr,
25402539
args_no_rcvr,
2541-
deref_args,
2540+
autoref_args,
25422541
false,
25432542
tuple_arguments);
25442543
ty::FnConverging(ty::mk_err())
@@ -2551,7 +2550,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
25512550
fty.sig.inputs.slice_from(1),
25522551
callee_expr,
25532552
args_no_rcvr,
2554-
deref_args,
2553+
autoref_args,
25552554
fty.sig.variadic,
25562555
tuple_arguments);
25572556
fty.sig.output
@@ -2571,7 +2570,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
25712570
fn_inputs: &[Ty<'tcx>],
25722571
_callee_expr: &ast::Expr,
25732572
args: &[&P<ast::Expr>],
2574-
deref_args: DerefArgs,
2573+
autoref_args: AutorefArgs,
25752574
variadic: bool,
25762575
tuple_arguments: TupleArgumentsFlag) {
25772576
let tcx = fcx.ccx.tcx;
@@ -2674,8 +2673,8 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
26742673
debug!("checking the argument");
26752674
let mut formal_ty = formal_tys[i];
26762675

2677-
match deref_args {
2678-
DoDerefArgs => {
2676+
match autoref_args {
2677+
AutorefArgs::Yes => {
26792678
match formal_ty.sty {
26802679
ty::ty_rptr(_, mt) => formal_ty = mt.ty,
26812680
ty::ty_err => (),
@@ -2690,7 +2689,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
26902689
}
26912690
}
26922691
}
2693-
DontDerefArgs => {}
2692+
AutorefArgs::No => {}
26942693
}
26952694

26962695
check_expr_coercable_to_type(fcx, &***arg, formal_ty);
@@ -2905,12 +2904,12 @@ pub fn lookup_tup_field_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
29052904
// Controls whether the arguments are automatically referenced. This is useful
29062905
// for overloaded binary and unary operators.
29072906
#[deriving(PartialEq)]
2908-
pub enum DerefArgs {
2909-
DontDerefArgs,
2910-
DoDerefArgs
2907+
pub enum AutorefArgs {
2908+
Yes,
2909+
No,
29112910
}
29122911

2913-
impl Copy for DerefArgs {}
2912+
impl Copy for AutorefArgs {}
29142913

29152914
/// Controls whether the arguments are tupled. This is used for the call
29162915
/// operator.
@@ -2998,7 +2997,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
29982997
fn_sig.inputs.as_slice(),
29992998
f,
30002999
args,
3001-
DontDerefArgs,
3000+
AutorefArgs::No,
30023001
fn_sig.variadic,
30033002
DontTupleArguments);
30043003

@@ -3048,7 +3047,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
30483047
fn_ty,
30493048
expr,
30503049
args.as_slice(),
3051-
DontDerefArgs,
3050+
AutorefArgs::No,
30523051
DontTupleArguments);
30533052

30543053
write_call(fcx, expr, ret_ty);
@@ -3132,7 +3131,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
31323131
lhs: &'a ast::Expr,
31333132
rhs: Option<&P<ast::Expr>>,
31343133
unbound_method: F,
3135-
deref_args: DerefArgs) -> Ty<'tcx> where
3134+
autoref_args: AutorefArgs) -> Ty<'tcx> where
31363135
F: FnOnce(),
31373136
{
31383137
let method = match trait_did {
@@ -3148,7 +3147,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
31483147
// traits that don't force left and right to have same
31493148
// type.
31503149
let (adj_ty, adjustment) = match lhs_ty.sty {
3151-
ty::ty_rptr(r_in, mt) if deref_args == DoDerefArgs => {
3150+
ty::ty_rptr(r_in, mt) => {
31523151
let r_adj = fcx.infcx().next_region_var(infer::Autoref(lhs.span));
31533152
fcx.mk_subr(infer::Reborrow(lhs.span), r_adj, r_in);
31543153
let adjusted_ty = ty::mk_rptr(fcx.tcx(), r_adj, mt);
@@ -3185,7 +3184,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
31853184
method_ty,
31863185
op_ex,
31873186
args.as_slice(),
3188-
deref_args,
3187+
autoref_args,
31893188
DontTupleArguments) {
31903189
ty::FnConverging(result_type) => result_type,
31913190
ty::FnDiverging => ty::mk_err()
@@ -3201,7 +3200,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
32013200
expected_ty,
32023201
op_ex,
32033202
args.as_slice(),
3204-
deref_args,
3203+
autoref_args,
32053204
DontTupleArguments);
32063205
ty::mk_err()
32073206
}
@@ -3320,23 +3319,23 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
33203319
rhs: &P<ast::Expr>) -> Ty<'tcx> {
33213320
let tcx = fcx.ccx.tcx;
33223321
let lang = &tcx.lang_items;
3323-
let (name, trait_did, deref_args) = match op {
3324-
ast::BiAdd => ("add", lang.add_trait(), DontDerefArgs),
3325-
ast::BiSub => ("sub", lang.sub_trait(), DontDerefArgs),
3326-
ast::BiMul => ("mul", lang.mul_trait(), DontDerefArgs),
3327-
ast::BiDiv => ("div", lang.div_trait(), DontDerefArgs),
3328-
ast::BiRem => ("rem", lang.rem_trait(), DontDerefArgs),
3329-
ast::BiBitXor => ("bitxor", lang.bitxor_trait(), DontDerefArgs),
3330-
ast::BiBitAnd => ("bitand", lang.bitand_trait(), DontDerefArgs),
3331-
ast::BiBitOr => ("bitor", lang.bitor_trait(), DontDerefArgs),
3332-
ast::BiShl => ("shl", lang.shl_trait(), DontDerefArgs),
3333-
ast::BiShr => ("shr", lang.shr_trait(), DontDerefArgs),
3334-
ast::BiLt => ("lt", lang.ord_trait(), DoDerefArgs),
3335-
ast::BiLe => ("le", lang.ord_trait(), DoDerefArgs),
3336-
ast::BiGe => ("ge", lang.ord_trait(), DoDerefArgs),
3337-
ast::BiGt => ("gt", lang.ord_trait(), DoDerefArgs),
3338-
ast::BiEq => ("eq", lang.eq_trait(), DoDerefArgs),
3339-
ast::BiNe => ("ne", lang.eq_trait(), DoDerefArgs),
3322+
let (name, trait_did) = match op {
3323+
ast::BiAdd => ("add", lang.add_trait()),
3324+
ast::BiSub => ("sub", lang.sub_trait()),
3325+
ast::BiMul => ("mul", lang.mul_trait()),
3326+
ast::BiDiv => ("div", lang.div_trait()),
3327+
ast::BiRem => ("rem", lang.rem_trait()),
3328+
ast::BiBitXor => ("bitxor", lang.bitxor_trait()),
3329+
ast::BiBitAnd => ("bitand", lang.bitand_trait()),
3330+
ast::BiBitOr => ("bitor", lang.bitor_trait()),
3331+
ast::BiShl => ("shl", lang.shl_trait()),
3332+
ast::BiShr => ("shr", lang.shr_trait()),
3333+
ast::BiLt => ("lt", lang.ord_trait()),
3334+
ast::BiLe => ("le", lang.ord_trait()),
3335+
ast::BiGe => ("ge", lang.ord_trait()),
3336+
ast::BiGt => ("gt", lang.ord_trait()),
3337+
ast::BiEq => ("eq", lang.eq_trait()),
3338+
ast::BiNe => ("ne", lang.eq_trait()),
33403339
ast::BiAnd | ast::BiOr => {
33413340
check_expr(fcx, &**rhs);
33423341
return ty::mk_err();
@@ -3349,7 +3348,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
33493348
ast_util::binop_to_string(op),
33503349
actual)
33513350
}, lhs_resolved_t, None)
3352-
}, deref_args)
3351+
}, if ast_util::is_by_value_binop(op) { AutorefArgs::No } else { AutorefArgs::Yes })
33533352
}
33543353

33553354
fn check_user_unop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
@@ -3365,7 +3364,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
33653364
format!("cannot apply unary operator `{}` to type `{}`",
33663365
op_str, actual)
33673366
}, rhs_t, None);
3368-
}, DontDerefArgs)
3367+
}, AutorefArgs::Yes)
33693368
}
33703369

33713370
// Check field access expressions

0 commit comments

Comments
 (0)