Tell expr_use_visitor which binops are by value

This commit is contained in:
Jorge Aparicio 2014-12-01 14:47:06 -05:00
parent f64e52a7f7
commit 5038f5a70c

View file

@ -30,7 +30,7 @@ use middle::ty::{MethodStatic, MethodStaticUnboxedClosure};
use util::ppaux::Repr; use util::ppaux::Repr;
use std::kinds; use std::kinds;
use syntax::ast; use syntax::{ast, ast_util};
use syntax::ptr::P; use syntax::ptr::P;
use syntax::codemap::Span; use syntax::codemap::Span;
@ -438,7 +438,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
ast::ExprPath(..) => { } ast::ExprPath(..) => { }
ast::ExprUnary(ast::UnDeref, ref base) => { // *base ast::ExprUnary(ast::UnDeref, ref base) => { // *base
if !self.walk_overloaded_operator(expr, &**base, Vec::new()) { if !self.walk_overloaded_operator(expr, &**base, Vec::new(), None) {
self.select_from_expr(&**base); self.select_from_expr(&**base);
} }
} }
@ -452,7 +452,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
} }
ast::ExprIndex(ref lhs, ref rhs) => { // lhs[rhs] ast::ExprIndex(ref lhs, ref rhs) => { // lhs[rhs]
if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs]) { if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs], None) {
self.select_from_expr(&**lhs); self.select_from_expr(&**lhs);
self.consume_expr(&**rhs); self.consume_expr(&**rhs);
} }
@ -465,7 +465,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
(&None, &Some(ref e)) => vec![&**e], (&None, &Some(ref e)) => vec![&**e],
(&None, &None) => Vec::new() (&None, &None) => Vec::new()
}; };
let overloaded = self.walk_overloaded_operator(expr, &**base, args); let overloaded = self.walk_overloaded_operator(expr, &**base, args, None);
assert!(overloaded); assert!(overloaded);
} }
@ -570,13 +570,14 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
} }
ast::ExprUnary(_, ref lhs) => { ast::ExprUnary(_, ref lhs) => {
if !self.walk_overloaded_operator(expr, &**lhs, Vec::new()) { if !self.walk_overloaded_operator(expr, &**lhs, Vec::new(), None) {
self.consume_expr(&**lhs); self.consume_expr(&**lhs);
} }
} }
ast::ExprBinary(_, ref lhs, ref rhs) => { ast::ExprBinary(op, ref lhs, ref rhs) => {
if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs]) { if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs], Some(op))
{
self.consume_expr(&**lhs); self.consume_expr(&**lhs);
self.consume_expr(&**rhs); self.consume_expr(&**rhs);
} }
@ -911,13 +912,24 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
fn walk_overloaded_operator(&mut self, fn walk_overloaded_operator(&mut self,
expr: &ast::Expr, expr: &ast::Expr,
receiver: &ast::Expr, receiver: &ast::Expr,
rhs: Vec<&ast::Expr>) rhs: Vec<&ast::Expr>,
binop: Option<ast::BinOp>)
-> bool -> bool
{ {
if !self.typer.is_method_call(expr.id) { if !self.typer.is_method_call(expr.id) {
return false; return false;
} }
match binop {
Some(binop) if ast_util::is_by_value_binop(binop) => {
self.consume_expr(receiver);
self.consume_expr(rhs[0]);
return true;
},
_ => {},
}
self.walk_expr(receiver); self.walk_expr(receiver);
// Arguments (but not receivers) to overloaded operator // Arguments (but not receivers) to overloaded operator