@@ -2988,19 +2988,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
2988
2988
let result_t = if is_binop_assignment == SimpleBinop {
2989
2989
check_user_binop ( fcx, expr, lhs, lhs_t, op, rhs)
2990
2990
} else {
2991
- fcx. type_error_message ( expr. span ,
2992
- |actual| {
2993
- format ! ( "binary assignment \
2994
- operation `{}=` \
2995
- cannot be applied to \
2996
- type `{}`",
2997
- ast_util:: binop_to_string( op. node) ,
2998
- actual)
2999
- } ,
3000
- lhs_t,
3001
- None ) ;
3002
- check_expr ( fcx, & * * rhs) ;
3003
- fcx. tcx ( ) . types . err
2991
+ check_user_binop_assign ( fcx, expr, lhs, lhs_t, op, rhs)
3004
2992
} ;
3005
2993
3006
2994
fcx. write_ty ( expr. id , result_t) ;
@@ -3049,6 +3037,42 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
3049
3037
} , if ast_util:: is_by_value_binop ( op. node ) { AutorefArgs :: No } else { AutorefArgs :: Yes } )
3050
3038
}
3051
3039
3040
+ fn check_user_binop_assign < ' a , ' tcx > ( fcx : & FnCtxt < ' a , ' tcx > ,
3041
+ ex : & ' tcx ast:: Expr ,
3042
+ lhs_expr : & ' tcx ast:: Expr ,
3043
+ lhs_resolved_t : Ty < ' tcx > ,
3044
+ op : ast:: BinOp ,
3045
+ rhs : & ' tcx P < ast:: Expr > ) -> Ty < ' tcx > {
3046
+ let tcx = fcx. ccx . tcx ;
3047
+ let lang = & tcx. lang_items ;
3048
+ let ( name, trait_did) = match op. node {
3049
+ ast:: BiAdd => ( "add_assign" , lang. add_assign_trait ( ) ) ,
3050
+ ast:: BiSub => ( "sub_assign" , lang. sub_assign_trait ( ) ) ,
3051
+ ast:: BiMul => ( "mul_assign" , lang. mul_assign_trait ( ) ) ,
3052
+ ast:: BiDiv => ( "div_assign" , lang. div_assign_trait ( ) ) ,
3053
+ ast:: BiRem => ( "rem_assign" , lang. rem_assign_trait ( ) ) ,
3054
+ ast:: BiBitXor => ( "bitxor_assign" , lang. bitxor_assign_trait ( ) ) ,
3055
+ ast:: BiBitAnd => ( "bitand_assign" , lang. bitand_assign_trait ( ) ) ,
3056
+ ast:: BiBitOr => ( "bitor_assign" , lang. bitor_assign_trait ( ) ) ,
3057
+ ast:: BiShl => ( "shl_assign" , lang. shl_assign_trait ( ) ) ,
3058
+ ast:: BiShr => ( "shr_assign" , lang. shr_assign_trait ( ) ) ,
3059
+ ast:: BiLt | ast:: BiLe | ast:: BiGe | ast:: BiGt | ast:: BiEq | ast:: BiNe | ast:: BiAnd |
3060
+ ast:: BiOr =>
3061
+ {
3062
+ check_expr ( fcx, & * * rhs) ;
3063
+ return tcx. types . err ;
3064
+ }
3065
+ } ;
3066
+ lookup_op_method ( fcx, ex, lhs_resolved_t, token:: intern ( name) ,
3067
+ trait_did, lhs_expr, Some ( rhs) , || {
3068
+ fcx. type_error_message ( ex. span , |actual| {
3069
+ format ! ( "binary operation `{}=` cannot be applied to type `{}`" ,
3070
+ ast_util:: binop_to_string( op. node) ,
3071
+ actual)
3072
+ } , lhs_resolved_t, None )
3073
+ } , AutorefArgs :: Yes )
3074
+ }
3075
+
3052
3076
fn check_user_unop < ' a , ' tcx > ( fcx : & FnCtxt < ' a , ' tcx > ,
3053
3077
op_str : & str ,
3054
3078
mname : & str ,
@@ -3480,10 +3504,6 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
3480
3504
ast:: ExprAssignOp ( op, ref lhs, ref rhs) => {
3481
3505
check_binop ( fcx, expr, op, & * * lhs, rhs, BinopAssignment ) ;
3482
3506
3483
- let lhs_t = fcx. expr_ty ( & * * lhs) ;
3484
- let result_t = fcx. expr_ty ( expr) ;
3485
- demand:: suptype ( fcx, expr. span , result_t, lhs_t) ;
3486
-
3487
3507
let tcx = fcx. tcx ( ) ;
3488
3508
if !ty:: expr_is_lval ( tcx, & * * lhs) {
3489
3509
span_err ! ( tcx. sess, lhs. span, E0067 , "illegal left-hand side expression" ) ;
@@ -3494,7 +3514,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
3494
3514
// Overwrite result of check_binop...this preserves existing behavior
3495
3515
// but seems quite dubious with regard to user-defined methods
3496
3516
// and so forth. - Niko
3497
- if !ty:: type_is_error ( result_t ) {
3517
+ if !ty:: type_is_error ( fcx . expr_ty ( expr ) ) {
3498
3518
fcx. write_nil ( expr. id ) ;
3499
3519
}
3500
3520
}
0 commit comments