Improve invalid operator assignment handling.
This commit is contained in:
parent
72a52522ca
commit
02d86216f3
3 changed files with 34 additions and 14 deletions
|
@ -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)]
|
#[deriving(Eq)]
|
||||||
enum AllowOverloadedOperatorsFlag {
|
enum IsBinopAssignment{
|
||||||
AllowOverloadedOperators,
|
SimpleBinop,
|
||||||
DontAllowOverloadedOperators,
|
BinopAssignment,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
|
@ -2086,7 +2088,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||||
rhs: @ast::Expr,
|
rhs: @ast::Expr,
|
||||||
// Used only in the error case
|
// Used only in the error case
|
||||||
expected_result: Option<ty::t>,
|
expected_result: Option<ty::t>,
|
||||||
allow_overloaded_operators: AllowOverloadedOperatorsFlag
|
is_binop_assignment: IsBinopAssignment
|
||||||
) {
|
) {
|
||||||
let tcx = fcx.ccx.tcx;
|
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;
|
let result_t;
|
||||||
if allow_overloaded_operators == AllowOverloadedOperators {
|
if is_binop_assignment == SimpleBinop {
|
||||||
result_t = check_user_binop(fcx,
|
result_t = check_user_binop(fcx,
|
||||||
callee_id,
|
callee_id,
|
||||||
expr,
|
expr,
|
||||||
|
@ -2150,13 +2152,14 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||||
} else {
|
} else {
|
||||||
fcx.type_error_message(expr.span,
|
fcx.type_error_message(expr.span,
|
||||||
|actual| {
|
|actual| {
|
||||||
format!("binary operation {} cannot be \
|
format!("binary assignment operation \
|
||||||
applied to type `{}`",
|
{}= cannot be applied to type `{}`",
|
||||||
ast_util::binop_to_str(op),
|
ast_util::binop_to_str(op),
|
||||||
actual)
|
actual)
|
||||||
},
|
},
|
||||||
lhs_t,
|
lhs_t,
|
||||||
None);
|
None);
|
||||||
|
check_expr(fcx, rhs);
|
||||||
result_t = ty::mk_err();
|
result_t = ty::mk_err();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2760,7 +2763,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||||
lhs,
|
lhs,
|
||||||
rhs,
|
rhs,
|
||||||
expected,
|
expected,
|
||||||
AllowOverloadedOperators);
|
SimpleBinop);
|
||||||
|
|
||||||
let lhs_ty = fcx.expr_ty(lhs);
|
let lhs_ty = fcx.expr_ty(lhs);
|
||||||
let rhs_ty = fcx.expr_ty(rhs);
|
let rhs_ty = fcx.expr_ty(rhs);
|
||||||
|
@ -2781,7 +2784,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||||
lhs,
|
lhs,
|
||||||
rhs,
|
rhs,
|
||||||
expected,
|
expected,
|
||||||
DontAllowOverloadedOperators);
|
BinopAssignment);
|
||||||
|
|
||||||
let lhs_t = fcx.expr_ty(lhs);
|
let lhs_t = fcx.expr_ty(lhs);
|
||||||
let result_t = fcx.expr_ty(expr);
|
let result_t = fcx.expr_ty(expr);
|
||||||
|
|
17
src/test/compile-fail/assignment-operator-unimplemented.rs
Normal file
17
src/test/compile-fail/assignment-operator-unimplemented.rs
Normal file
|
@ -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`
|
||||||
|
}
|
|
@ -11,5 +11,5 @@
|
||||||
// Regression test for issue #5239
|
// Regression test for issue #5239
|
||||||
|
|
||||||
fn main() {
|
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`
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue