提交 f5569ecd 编写于 作者: J Jorge Aparicio

address Niko's comments

上级 3ae3a5fc
......@@ -526,13 +526,10 @@ pub fn walk_expr(&mut self, expr: &hir::Expr) {
}
hir::ExprAssignOp(op, ref lhs, ref rhs) => {
let pass_args = if ::rustc_front::util::is_by_value_binop(op.node) {
PassArgs::ByValue
} else {
PassArgs::ByRef
};
// NB All our assignment operations take the RHS by value
assert!(::rustc_front::util::is_by_value_binop(op.node));
if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs], pass_args) {
if !self.walk_overloaded_operator(expr, lhs, vec![rhs], PassArgs::ByValue) {
self.mutate_expr(expr, &**lhs, WriteAndRead);
self.consume_expr(&**rhs);
}
......
......@@ -36,7 +36,7 @@ pub fn check_binop_assign<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
let lhs_ty = fcx.resolve_type_vars_if_possible(fcx.expr_ty(lhs_expr));
let (rhs_ty, return_ty) =
check_overloaded_binop(fcx, expr, lhs_expr, lhs_ty, rhs_expr, op, true);
check_overloaded_binop(fcx, expr, lhs_expr, lhs_ty, rhs_expr, op, IsAssign::Yes);
let rhs_ty = fcx.resolve_type_vars_if_possible(rhs_ty);
if !lhs_ty.is_ty_var() && !rhs_ty.is_ty_var() && is_builtin_binop(lhs_ty, rhs_ty, op) {
......@@ -83,7 +83,7 @@ pub fn check_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
// overloaded. This is the way to be most flexible w/r/t
// types that get inferred.
let (rhs_ty, return_ty) =
check_overloaded_binop(fcx, expr, lhs_expr, lhs_ty, rhs_expr, op, false);
check_overloaded_binop(fcx, expr, lhs_expr, lhs_ty, rhs_expr, op, IsAssign::No);
// Supply type inference hints if relevant. Probably these
// hints should be enforced during select as part of the
......@@ -156,15 +156,15 @@ fn check_overloaded_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
lhs_ty: Ty<'tcx>,
rhs_expr: &'tcx hir::Expr,
op: hir::BinOp,
assign: bool)
is_assign: IsAssign)
-> (Ty<'tcx>, Ty<'tcx>)
{
debug!("check_overloaded_binop(expr.id={}, lhs_ty={:?}, assign={})",
debug!("check_overloaded_binop(expr.id={}, lhs_ty={:?}, is_assign={:?})",
expr.id,
lhs_ty,
assign);
is_assign);
let (name, trait_def_id) = name_and_trait_def_id(fcx, op, assign);
let (name, trait_def_id) = name_and_trait_def_id(fcx, op, is_assign);
// NB: As we have not yet type-checked the RHS, we don't have the
// type at hand. Make a variable to represent it. The whole reason
......@@ -181,7 +181,7 @@ fn check_overloaded_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
Err(()) => {
// error types are considered "builtin"
if !lhs_ty.references_error() {
if assign {
if let IsAssign::Yes = is_assign {
span_err!(fcx.tcx().sess, lhs_expr.span, E0368,
"binary assignment operation `{}=` cannot be applied to type `{}`",
hir_util::binop_to_string(op.node),
......@@ -230,11 +230,11 @@ pub fn check_user_unop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
fn name_and_trait_def_id(fcx: &FnCtxt,
op: hir::BinOp,
assign: bool)
is_assign: IsAssign)
-> (&'static str, Option<DefId>) {
let lang = &fcx.tcx().lang_items;
if assign {
if let IsAssign::Yes = is_assign {
match op.node {
hir::BiAdd => ("add_assign", lang.add_assign_trait()),
hir::BiSub => ("sub_assign", lang.sub_assign_trait()),
......@@ -383,6 +383,13 @@ fn from(op: hir::BinOp) -> BinOpCategory {
}
}
/// Whether the binary operation is an assignment (`a += b`), or not (`a + b`)
#[derive(Clone, Copy, Debug)]
enum IsAssign {
No,
Yes,
}
/// Returns true if this is a built-in arithmetic operation (e.g. u32
/// + u32, i16x4 == i16x4) and false if these types would have to be
/// overloaded to be legal. There are two reasons that we distinguish
......
......@@ -122,8 +122,10 @@ fn fix_scalar_binary_expr(&mut self, e: &hir::Expr) {
let tcx = self.tcx();
if let hir::ExprAssignOp(..) = e.node {
if !tcx.sess.features.borrow().augmented_assignments &&
!self.fcx.expr_ty(e).references_error() {
if
!tcx.sess.features.borrow().augmented_assignments &&
!self.fcx.expr_ty(e).references_error()
{
tcx.sess.span_err(
e.span,
"overloaded augmented assignments are not stable");
......
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::ops::AddAssign;
//~^ error: use of unstable library feature 'op_assign_traits'
struct Int(i32);
impl AddAssign for Int {
//~^ error: use of unstable library feature 'op_assign_traits'
fn add_assign(&mut self, _: Int) {
//~^ error: use of unstable library feature 'op_assign_traits'
unimplemented!()
}
}
fn main() {}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册