Skip to content

Commit 02d8621

Browse files
committed
Improve invalid operator assignment handling.
1 parent 72a5252 commit 02d8621

File tree

3 files changed

+34
-14
lines changed

3 files changed

+34
-14
lines changed

src/librustc/middle/typeck/check/mod.rs

+16-13
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,13 @@ impl PurityState {
213213
}
214214
}
215215

216-
/// Whether `check_binop` allows overloaded operators to be invoked.
216+
/// Whether `check_binop` is part of an assignment or not.
217+
/// Used to know wether we allow user overloads and to print
218+
/// better messages on error.
217219
#[deriving(Eq)]
218-
enum AllowOverloadedOperatorsFlag {
219-
AllowOverloadedOperators,
220-
DontAllowOverloadedOperators,
220+
enum IsBinopAssignment{
221+
SimpleBinop,
222+
BinopAssignment,
221223
}
222224

223225
#[deriving(Clone)]
@@ -2086,7 +2088,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
20862088
rhs: @ast::Expr,
20872089
// Used only in the error case
20882090
expected_result: Option<ty::t>,
2089-
allow_overloaded_operators: AllowOverloadedOperatorsFlag
2091+
is_binop_assignment: IsBinopAssignment
20902092
) {
20912093
let tcx = fcx.ccx.tcx;
20922094

@@ -2136,9 +2138,9 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
21362138

21372139
}
21382140

2139-
// Check for overloaded operators if allowed.
2141+
// Check for overloaded operators if not an assignment.
21402142
let result_t;
2141-
if allow_overloaded_operators == AllowOverloadedOperators {
2143+
if is_binop_assignment == SimpleBinop {
21422144
result_t = check_user_binop(fcx,
21432145
callee_id,
21442146
expr,
@@ -2150,13 +2152,14 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
21502152
} else {
21512153
fcx.type_error_message(expr.span,
21522154
|actual| {
2153-
format!("binary operation {} cannot be \
2154-
applied to type `{}`",
2155-
ast_util::binop_to_str(op),
2156-
actual)
2155+
format!("binary assignment operation \
2156+
{}= cannot be applied to type `{}`",
2157+
ast_util::binop_to_str(op),
2158+
actual)
21572159
},
21582160
lhs_t,
21592161
None);
2162+
check_expr(fcx, rhs);
21602163
result_t = ty::mk_err();
21612164
}
21622165

@@ -2760,7 +2763,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
27602763
lhs,
27612764
rhs,
27622765
expected,
2763-
AllowOverloadedOperators);
2766+
SimpleBinop);
27642767

27652768
let lhs_ty = fcx.expr_ty(lhs);
27662769
let rhs_ty = fcx.expr_ty(rhs);
@@ -2781,7 +2784,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
27812784
lhs,
27822785
rhs,
27832786
expected,
2784-
DontAllowOverloadedOperators);
2787+
BinopAssignment);
27852788

27862789
let lhs_t = fcx.expr_ty(lhs);
27872790
let result_t = fcx.expr_ty(expr);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
struct Foo;
12+
13+
fn main() {
14+
let mut a = Foo;
15+
let ref b = Foo;
16+
a += *b; //~ Error: binary assignment operation += cannot be applied to type `Foo`
17+
}

src/test/compile-fail/issue-5239-1.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@
1111
// Regression test for issue #5239
1212

1313
fn main() {
14-
let x: |int| -> int = |ref x| { x += 1; }; //~ ERROR binary operation + cannot be applied to type `&int`
14+
let x: |int| -> int = |ref x| { x += 1; }; //~ ERROR binary assignment operation += cannot be applied to type `&int`
1515
}

0 commit comments

Comments
 (0)