@@ -2926,39 +2926,78 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
2926
2926
lhs_expr : & ' tcx ast:: Expr ,
2927
2927
lhs_resolved_t : Ty < ' tcx > ,
2928
2928
op : ast:: BinOp ,
2929
- rhs : & ' tcx P < ast:: Expr > ) -> Ty < ' tcx > {
2929
+ rhs : & ' tcx P < ast:: Expr > )
2930
+ -> Ty < ' tcx >
2931
+ {
2930
2932
let tcx = fcx. ccx . tcx ;
2931
2933
let lang = & tcx. lang_items ;
2932
- let ( name, trait_did) = match op. node {
2933
- ast:: BiAdd => ( "add" , lang. add_trait ( ) ) ,
2934
- ast:: BiSub => ( "sub" , lang. sub_trait ( ) ) ,
2935
- ast:: BiMul => ( "mul" , lang. mul_trait ( ) ) ,
2936
- ast:: BiDiv => ( "div" , lang. div_trait ( ) ) ,
2937
- ast:: BiRem => ( "rem" , lang. rem_trait ( ) ) ,
2938
- ast:: BiBitXor => ( "bitxor" , lang. bitxor_trait ( ) ) ,
2939
- ast:: BiBitAnd => ( "bitand" , lang. bitand_trait ( ) ) ,
2940
- ast:: BiBitOr => ( "bitor" , lang. bitor_trait ( ) ) ,
2941
- ast:: BiShl => ( "shl" , lang. shl_trait ( ) ) ,
2942
- ast:: BiShr => ( "shr" , lang. shr_trait ( ) ) ,
2943
- ast:: BiLt => ( "lt" , lang. ord_trait ( ) ) ,
2944
- ast:: BiLe => ( "le" , lang. ord_trait ( ) ) ,
2945
- ast:: BiGe => ( "ge" , lang. ord_trait ( ) ) ,
2946
- ast:: BiGt => ( "gt" , lang. ord_trait ( ) ) ,
2947
- ast:: BiEq => ( "eq" , lang. eq_trait ( ) ) ,
2948
- ast:: BiNe => ( "ne" , lang. eq_trait ( ) ) ,
2934
+ let ( name, trait_did, is_comparison ) = match op. node {
2935
+ ast:: BiAdd => ( "add" , lang. add_trait ( ) , false ) ,
2936
+ ast:: BiSub => ( "sub" , lang. sub_trait ( ) , false ) ,
2937
+ ast:: BiMul => ( "mul" , lang. mul_trait ( ) , false ) ,
2938
+ ast:: BiDiv => ( "div" , lang. div_trait ( ) , false ) ,
2939
+ ast:: BiRem => ( "rem" , lang. rem_trait ( ) , false ) ,
2940
+ ast:: BiBitXor => ( "bitxor" , lang. bitxor_trait ( ) , false ) ,
2941
+ ast:: BiBitAnd => ( "bitand" , lang. bitand_trait ( ) , false ) ,
2942
+ ast:: BiBitOr => ( "bitor" , lang. bitor_trait ( ) , false ) ,
2943
+ ast:: BiShl => ( "shl" , lang. shl_trait ( ) , false ) ,
2944
+ ast:: BiShr => ( "shr" , lang. shr_trait ( ) , false ) ,
2945
+ ast:: BiLt => ( "lt" , lang. ord_trait ( ) , true ) ,
2946
+ ast:: BiLe => ( "le" , lang. ord_trait ( ) , true ) ,
2947
+ ast:: BiGe => ( "ge" , lang. ord_trait ( ) , true ) ,
2948
+ ast:: BiGt => ( "gt" , lang. ord_trait ( ) , true ) ,
2949
+ ast:: BiEq => ( "eq" , lang. eq_trait ( ) , true ) ,
2950
+ ast:: BiNe => ( "ne" , lang. eq_trait ( ) , true ) ,
2949
2951
ast:: BiAnd | ast:: BiOr => {
2950
2952
// TODO(japaric) use span_bug
2951
2953
unreachable ! ( ) ;
2952
2954
}
2953
2955
} ;
2954
- lookup_op_method ( fcx, ex, lhs_resolved_t, token:: intern ( name) ,
2955
- trait_did, lhs_expr, Some ( rhs) , || {
2956
+
2957
+ let autoref_args =
2958
+ if ast_util:: is_by_value_binop ( op. node ) {
2959
+ AutorefArgs :: No
2960
+ } else {
2961
+ AutorefArgs :: Yes
2962
+ } ;
2963
+
2964
+ let report_error = || {
2956
2965
fcx. type_error_message ( ex. span , |actual| {
2957
2966
format ! ( "binary operation `{}` cannot be applied to type `{}`" ,
2958
2967
ast_util:: binop_to_string( op. node) ,
2959
2968
actual)
2960
2969
} , lhs_resolved_t, None )
2961
- } , if ast_util:: is_by_value_binop ( op. node ) { AutorefArgs :: No } else { AutorefArgs :: Yes } )
2970
+ } ;
2971
+
2972
+ let output_ty =
2973
+ lookup_op_method ( fcx,
2974
+ ex,
2975
+ lhs_resolved_t,
2976
+ token:: intern ( name) ,
2977
+ trait_did,
2978
+ lhs_expr,
2979
+ Some ( rhs) ,
2980
+ report_error,
2981
+ autoref_args) ;
2982
+
2983
+ // Special case rule to aid type inference: operational
2984
+ // operators always yield boolean; for non-operational
2985
+ // operators, if both left and right hand side types are
2986
+ // integral, then the result type also be the same as the LHS.
2987
+ if
2988
+ is_comparison
2989
+ {
2990
+ demand:: eqtype ( fcx, ex. span , ty:: mk_bool ( fcx. tcx ( ) ) , output_ty) ;
2991
+ } else if
2992
+ ty:: type_is_integral ( lhs_resolved_t) && {
2993
+ let rhs_resolved_t = fcx. resolve_type_vars_if_possible ( fcx. expr_ty ( rhs) ) ;
2994
+ ty:: type_is_integral ( rhs_resolved_t)
2995
+ }
2996
+ {
2997
+ demand:: eqtype ( fcx, ex. span , lhs_resolved_t, output_ty) ;
2998
+ }
2999
+
3000
+ output_ty
2962
3001
}
2963
3002
2964
3003
fn check_user_unop < ' a , ' tcx > ( fcx : & FnCtxt < ' a , ' tcx > ,
0 commit comments