]> git.lizzy.rs Git - rust.git/commitdiff
Improve invalid operator assignment handling.
authorRaphael Catolino <raphael.catolino@gmail.com>
Fri, 10 Jan 2014 19:46:20 +0000 (20:46 +0100)
committerRaphael Catolino <raphael.catolino@gmail.com>
Fri, 10 Jan 2014 19:46:20 +0000 (20:46 +0100)
src/librustc/middle/typeck/check/mod.rs
src/test/compile-fail/assignment-operator-unimplemented.rs [new file with mode: 0644]
src/test/compile-fail/issue-5239-1.rs

index f5bbcea431e51c6a6020fbd897428af99eb61fd4..5acca083d7939b765625b2b8d63762d3f5225186 100644 (file)
@@ -213,11 +213,13 @@ pub fn recurse(&mut self, blk: &ast::Block) -> 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 @@ fn check_binop(fcx: @FnCtxt,
                    rhs: @ast::Expr,
                    // Used only in the error case
                    expected_result: Option<ty::t>,
-                   allow_overloaded_operators: AllowOverloadedOperatorsFlag
+                   is_binop_assignment: IsBinopAssignment
                   ) {
         let tcx = fcx.ccx.tcx;
 
@@ -2136,9 +2138,9 @@ fn check_binop(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 @@ fn check_binop(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 @@ fn check_struct_enum_variant(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 @@ fn check_struct_enum_variant(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 (file)
index 0000000..96b0568
--- /dev/null
@@ -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 <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.
+
+struct Foo;
+
+fn main() {
+  let mut a = Foo;
+  let ref b = Foo;
+  a += *b; //~ Error: binary assignment operation += cannot be applied to type `Foo`
+}
index a316e3df042e03fb4aa7757148a00112c340b49e..f7ec0bf8ac10b1e8c8a61f45f53afce694b9064d 100644 (file)
@@ -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`
 }