]> git.lizzy.rs Git - rust.git/commitdiff
Address Niko's comments
authorJorge Aparicio <japaricious@gmail.com>
Wed, 3 Dec 2014 05:39:53 +0000 (00:39 -0500)
committerJorge Aparicio <japaricious@gmail.com>
Sun, 14 Dec 2014 01:16:34 +0000 (20:16 -0500)
src/librustc/middle/expr_use_visitor.rs
src/librustc_typeck/check/mod.rs

index 59872c69462071ea13498501dafbd2c403bf27a4..59344258833a6829d01b664a9b7c4921a5b73f1b 100644 (file)
@@ -329,6 +329,12 @@ macro_rules! return_if_err(
     )
 )
 
+/// Whether the elements of an overloaded operation are passed by value or by reference
+enum PassArgs {
+    ByValue,
+    ByRef,
+}
+
 impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
     pub fn new(delegate: &'d mut Delegate<'tcx>,
                typer: &'t TYPER,
@@ -438,7 +444,7 @@ pub fn walk_expr(&mut self, expr: &ast::Expr) {
             ast::ExprPath(..) => { }
 
             ast::ExprUnary(ast::UnDeref, ref base) => {      // *base
-                if !self.walk_overloaded_operator(expr, &**base, Vec::new(), None) {
+                if !self.walk_overloaded_operator(expr, &**base, Vec::new(), PassArgs::ByRef) {
                     self.select_from_expr(&**base);
                 }
             }
@@ -452,7 +458,7 @@ pub fn walk_expr(&mut self, expr: &ast::Expr) {
             }
 
             ast::ExprIndex(ref lhs, ref rhs) => {       // lhs[rhs]
-                if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs], None) {
+                if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs], PassArgs::ByRef) {
                     self.select_from_expr(&**lhs);
                     self.consume_expr(&**rhs);
                 }
@@ -465,7 +471,8 @@ pub fn walk_expr(&mut self, expr: &ast::Expr) {
                     (&None, &Some(ref e)) => vec![&**e],
                     (&None, &None) => Vec::new()
                 };
-                let overloaded = self.walk_overloaded_operator(expr, &**base, args, None);
+                let overloaded =
+                    self.walk_overloaded_operator(expr, &**base, args, PassArgs::ByRef);
                 assert!(overloaded);
             }
 
@@ -570,14 +577,19 @@ pub fn walk_expr(&mut self, expr: &ast::Expr) {
             }
 
             ast::ExprUnary(_, ref lhs) => {
-                if !self.walk_overloaded_operator(expr, &**lhs, Vec::new(), None) {
+                if !self.walk_overloaded_operator(expr, &**lhs, Vec::new(), PassArgs::ByRef) {
                     self.consume_expr(&**lhs);
                 }
             }
 
             ast::ExprBinary(op, ref lhs, ref rhs) => {
-                if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs], Some(op))
-                {
+                let pass_args = if ast_util::is_by_value_binop(op) {
+                    PassArgs::ByValue
+                } else {
+                    PassArgs::ByRef
+                };
+
+                if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs], pass_args) {
                     self.consume_expr(&**lhs);
                     self.consume_expr(&**rhs);
                 }
@@ -913,21 +925,21 @@ fn walk_overloaded_operator(&mut self,
                                 expr: &ast::Expr,
                                 receiver: &ast::Expr,
                                 rhs: Vec<&ast::Expr>,
-                                binop: Option<ast::BinOp>)
+                                pass_args: PassArgs)
                                 -> bool
     {
         if !self.typer.is_method_call(expr.id) {
             return false;
         }
 
-        match binop {
-            Some(binop) if ast_util::is_by_value_binop(binop) => {
+        match pass_args {
+            PassArgs::ByValue => {
                 self.consume_expr(receiver);
                 self.consume_expr(rhs[0]);
 
                 return true;
             },
-            _ => {},
+            PassArgs::ByRef => {},
         }
 
         self.walk_expr(receiver);
index 2dcb07e0fb502c635f62e84b654e07bf37941819..5f8991278b08c8388e279f6064b1c90635892fb8 100644 (file)
@@ -77,7 +77,6 @@
 */
 
 pub use self::LvaluePreference::*;
-pub use self::DerefArgs::*;
 pub use self::Expectation::*;
 use self::IsBinopAssignment::*;
 use self::TupleArgumentsFlag::*;
@@ -2117,7 +2116,7 @@ fn try_overloaded_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                                       method_callee.ty,
                                                       call_expression,
                                                       args,
-                                                      DontDerefArgs,
+                                                      AutorefArgs::No,
                                                       TupleArguments);
         fcx.inh.method_map.borrow_mut().insert(method_call, method_callee);
         write_call(fcx, call_expression, output_type);
@@ -2274,7 +2273,7 @@ fn try_overloaded_slice<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                 method_ty_or_err,
                                 expr,
                                 args.as_slice(),
-                                DoDerefArgs,
+                                AutorefArgs::Yes,
                                 DontTupleArguments);
 
     opt_method_ty.map(|method_ty| {
@@ -2480,7 +2479,7 @@ fn lookup_method_for_for_loop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                                   method_type,
                                                   iterator_expr,
                                                   &[],
-                                                  DontDerefArgs,
+                                                  AutorefArgs::No,
                                                   DontTupleArguments);
 
     match method {
@@ -2522,7 +2521,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                          method_fn_ty: Ty<'tcx>,
                                          callee_expr: &ast::Expr,
                                          args_no_rcvr: &[&P<ast::Expr>],
-                                         deref_args: DerefArgs,
+                                         autoref_args: AutorefArgs,
                                          tuple_arguments: TupleArgumentsFlag)
                                          -> ty::FnOutput<'tcx> {
     if ty::type_is_error(method_fn_ty) {
@@ -2538,7 +2537,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                              err_inputs.as_slice(),
                              callee_expr,
                              args_no_rcvr,
-                             deref_args,
+                             autoref_args,
                              false,
                              tuple_arguments);
         ty::FnConverging(ty::mk_err())
@@ -2551,7 +2550,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                      fty.sig.inputs.slice_from(1),
                                      callee_expr,
                                      args_no_rcvr,
-                                     deref_args,
+                                     autoref_args,
                                      fty.sig.variadic,
                                      tuple_arguments);
                 fty.sig.output
@@ -2571,7 +2570,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                   fn_inputs: &[Ty<'tcx>],
                                   _callee_expr: &ast::Expr,
                                   args: &[&P<ast::Expr>],
-                                  deref_args: DerefArgs,
+                                  autoref_args: AutorefArgs,
                                   variadic: bool,
                                   tuple_arguments: TupleArgumentsFlag) {
     let tcx = fcx.ccx.tcx;
@@ -2674,8 +2673,8 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                 debug!("checking the argument");
                 let mut formal_ty = formal_tys[i];
 
-                match deref_args {
-                    DoDerefArgs => {
+                match autoref_args {
+                    AutorefArgs::Yes => {
                         match formal_ty.sty {
                             ty::ty_rptr(_, mt) => formal_ty = mt.ty,
                             ty::ty_err => (),
@@ -2690,7 +2689,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                             }
                         }
                     }
-                    DontDerefArgs => {}
+                    AutorefArgs::No => {}
                 }
 
                 check_expr_coercable_to_type(fcx, &***arg, formal_ty);
@@ -2905,12 +2904,12 @@ pub fn lookup_tup_field_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
 // Controls whether the arguments are automatically referenced. This is useful
 // for overloaded binary and unary operators.
 #[deriving(PartialEq)]
-pub enum DerefArgs {
-    DontDerefArgs,
-    DoDerefArgs
+pub enum AutorefArgs {
+    Yes,
+    No,
 }
 
-impl Copy for DerefArgs {}
+impl Copy for AutorefArgs {}
 
 /// Controls whether the arguments are tupled. This is used for the call
 /// operator.
@@ -2998,7 +2997,7 @@ fn check_call(fcx: &FnCtxt,
                              fn_sig.inputs.as_slice(),
                              f,
                              args,
-                             DontDerefArgs,
+                             AutorefArgs::No,
                              fn_sig.variadic,
                              DontTupleArguments);
 
@@ -3048,7 +3047,7 @@ fn check_method_call(fcx: &FnCtxt,
                                                  fn_ty,
                                                  expr,
                                                  args.as_slice(),
-                                                 DontDerefArgs,
+                                                 AutorefArgs::No,
                                                  DontTupleArguments);
 
         write_call(fcx, expr, ret_ty);
@@ -3132,7 +3131,7 @@ fn lookup_op_method<'a, 'tcx, F>(fcx: &'a FnCtxt<'a, 'tcx>,
                                      lhs: &'a ast::Expr,
                                      rhs: Option<&P<ast::Expr>>,
                                      unbound_method: F,
-                                     deref_args: DerefArgs) -> Ty<'tcx> where
+                                     autoref_args: AutorefArgs) -> Ty<'tcx> where
         F: FnOnce(),
     {
         let method = match trait_did {
@@ -3148,7 +3147,7 @@ fn lookup_op_method<'a, 'tcx, F>(fcx: &'a FnCtxt<'a, 'tcx>,
                 //   traits that don't force left and right to have same
                 //   type.
                 let (adj_ty, adjustment) = match lhs_ty.sty {
-                    ty::ty_rptr(r_in, mt) if deref_args == DoDerefArgs => {
+                    ty::ty_rptr(r_in, mt) => {
                         let r_adj = fcx.infcx().next_region_var(infer::Autoref(lhs.span));
                         fcx.mk_subr(infer::Reborrow(lhs.span), r_adj, r_in);
                         let adjusted_ty = ty::mk_rptr(fcx.tcx(), r_adj, mt);
@@ -3185,7 +3184,7 @@ fn lookup_op_method<'a, 'tcx, F>(fcx: &'a FnCtxt<'a, 'tcx>,
                                             method_ty,
                                             op_ex,
                                             args.as_slice(),
-                                            deref_args,
+                                            autoref_args,
                                             DontTupleArguments) {
                     ty::FnConverging(result_type) => result_type,
                     ty::FnDiverging => ty::mk_err()
@@ -3201,7 +3200,7 @@ fn lookup_op_method<'a, 'tcx, F>(fcx: &'a FnCtxt<'a, 'tcx>,
                                             expected_ty,
                                             op_ex,
                                             args.as_slice(),
-                                            deref_args,
+                                            autoref_args,
                                             DontTupleArguments);
                 ty::mk_err()
             }
@@ -3320,23 +3319,23 @@ fn check_user_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                   rhs: &P<ast::Expr>) -> Ty<'tcx> {
         let tcx = fcx.ccx.tcx;
         let lang = &tcx.lang_items;
-        let (name, trait_did, deref_args) = match op {
-            ast::BiAdd => ("add", lang.add_trait(), DontDerefArgs),
-            ast::BiSub => ("sub", lang.sub_trait(), DontDerefArgs),
-            ast::BiMul => ("mul", lang.mul_trait(), DontDerefArgs),
-            ast::BiDiv => ("div", lang.div_trait(), DontDerefArgs),
-            ast::BiRem => ("rem", lang.rem_trait(), DontDerefArgs),
-            ast::BiBitXor => ("bitxor", lang.bitxor_trait(), DontDerefArgs),
-            ast::BiBitAnd => ("bitand", lang.bitand_trait(), DontDerefArgs),
-            ast::BiBitOr => ("bitor", lang.bitor_trait(), DontDerefArgs),
-            ast::BiShl => ("shl", lang.shl_trait(), DontDerefArgs),
-            ast::BiShr => ("shr", lang.shr_trait(), DontDerefArgs),
-            ast::BiLt => ("lt", lang.ord_trait(), DoDerefArgs),
-            ast::BiLe => ("le", lang.ord_trait(), DoDerefArgs),
-            ast::BiGe => ("ge", lang.ord_trait(), DoDerefArgs),
-            ast::BiGt => ("gt", lang.ord_trait(), DoDerefArgs),
-            ast::BiEq => ("eq", lang.eq_trait(), DoDerefArgs),
-            ast::BiNe => ("ne", lang.eq_trait(), DoDerefArgs),
+        let (name, trait_did) = match op {
+            ast::BiAdd => ("add", lang.add_trait()),
+            ast::BiSub => ("sub", lang.sub_trait()),
+            ast::BiMul => ("mul", lang.mul_trait()),
+            ast::BiDiv => ("div", lang.div_trait()),
+            ast::BiRem => ("rem", lang.rem_trait()),
+            ast::BiBitXor => ("bitxor", lang.bitxor_trait()),
+            ast::BiBitAnd => ("bitand", lang.bitand_trait()),
+            ast::BiBitOr => ("bitor", lang.bitor_trait()),
+            ast::BiShl => ("shl", lang.shl_trait()),
+            ast::BiShr => ("shr", lang.shr_trait()),
+            ast::BiLt => ("lt", lang.ord_trait()),
+            ast::BiLe => ("le", lang.ord_trait()),
+            ast::BiGe => ("ge", lang.ord_trait()),
+            ast::BiGt => ("gt", lang.ord_trait()),
+            ast::BiEq => ("eq", lang.eq_trait()),
+            ast::BiNe => ("ne", lang.eq_trait()),
             ast::BiAnd | ast::BiOr => {
                 check_expr(fcx, &**rhs);
                 return ty::mk_err();
@@ -3349,7 +3348,7 @@ fn check_user_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                         ast_util::binop_to_string(op),
                         actual)
             }, lhs_resolved_t, None)
-        }, deref_args)
+        }, if ast_util::is_by_value_binop(op) { AutorefArgs::No } else { AutorefArgs::Yes })
     }
 
     fn check_user_unop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
@@ -3365,7 +3364,7 @@ fn check_user_unop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                 format!("cannot apply unary operator `{}` to type `{}`",
                         op_str, actual)
             }, rhs_t, None);
-        }, DontDerefArgs)
+        }, AutorefArgs::Yes)
     }
 
     // Check field access expressions