diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index f5bbcea431e51..5acca083d7939 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -213,11 +213,13 @@ impl PurityState { } } -/// Whether `check_binop` allows overloaded operators to be invoked. +/// Whether `check_binop` is part of an assignment or not. +/// Used to know wether we allow user overloads and to print +/// better messages on error. #[deriving(Eq)] -enum AllowOverloadedOperatorsFlag { - AllowOverloadedOperators, - DontAllowOverloadedOperators, +enum IsBinopAssignment{ + SimpleBinop, + BinopAssignment, } #[deriving(Clone)] @@ -2086,7 +2088,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt, rhs: @ast::Expr, // Used only in the error case expected_result: Option, - allow_overloaded_operators: AllowOverloadedOperatorsFlag + is_binop_assignment: IsBinopAssignment ) { let tcx = fcx.ccx.tcx; @@ -2136,9 +2138,9 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt, } - // Check for overloaded operators if allowed. + // Check for overloaded operators if not an assignment. let result_t; - if allow_overloaded_operators == AllowOverloadedOperators { + if is_binop_assignment == SimpleBinop { result_t = check_user_binop(fcx, callee_id, expr, @@ -2150,13 +2152,14 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt, } else { fcx.type_error_message(expr.span, |actual| { - format!("binary operation {} cannot be \ - applied to type `{}`", - ast_util::binop_to_str(op), - actual) + format!("binary assignment operation \ + {}= cannot be applied to type `{}`", + ast_util::binop_to_str(op), + actual) }, lhs_t, None); + check_expr(fcx, rhs); result_t = ty::mk_err(); } @@ -2760,7 +2763,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt, lhs, rhs, expected, - AllowOverloadedOperators); + SimpleBinop); let lhs_ty = fcx.expr_ty(lhs); let rhs_ty = fcx.expr_ty(rhs); @@ -2781,7 +2784,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt, lhs, rhs, expected, - DontAllowOverloadedOperators); + BinopAssignment); let lhs_t = fcx.expr_ty(lhs); let result_t = fcx.expr_ty(expr); diff --git a/src/test/compile-fail/assignment-operator-unimplemented.rs b/src/test/compile-fail/assignment-operator-unimplemented.rs new file mode 100644 index 0000000000000..96b05681f1724 --- /dev/null +++ b/src/test/compile-fail/assignment-operator-unimplemented.rs @@ -0,0 +1,17 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Foo; + +fn main() { + let mut a = Foo; + let ref b = Foo; + a += *b; //~ Error: binary assignment operation += cannot be applied to type `Foo` +} diff --git a/src/test/compile-fail/issue-5239-1.rs b/src/test/compile-fail/issue-5239-1.rs index a316e3df042e0..f7ec0bf8ac10b 100644 --- a/src/test/compile-fail/issue-5239-1.rs +++ b/src/test/compile-fail/issue-5239-1.rs @@ -11,5 +11,5 @@ // Regression test for issue #5239 fn main() { - let x: |int| -> int = |ref x| { x += 1; }; //~ ERROR binary operation + cannot be applied to type `&int` + let x: |int| -> int = |ref x| { x += 1; }; //~ ERROR binary assignment operation += cannot be applied to type `&int` }