@@ -10,8 +10,7 @@ use chalk_ir::{
10
10
} ;
11
11
use hir_def:: {
12
12
expr:: {
13
- ArithOp , Array , BinaryOp , ClosureKind , CmpOp , Expr , ExprId , LabelId , Literal , Statement ,
14
- UnaryOp ,
13
+ ArithOp , Array , BinaryOp , ClosureKind , Expr , ExprId , LabelId , Literal , Statement , UnaryOp ,
15
14
} ,
16
15
generics:: TypeOrConstParamData ,
17
16
path:: { GenericArg , GenericArgs } ,
@@ -1017,11 +1016,21 @@ impl<'a> InferenceContext<'a> {
1017
1016
let ( trait_, func) = match trait_func {
1018
1017
Some ( it) => it,
1019
1018
None => {
1020
- let rhs_ty = self . builtin_binary_op_rhs_expectation ( op, lhs_ty. clone ( ) ) ;
1021
- let rhs_ty = self . infer_expr_coerce ( rhs, & Expectation :: from_option ( rhs_ty) ) ;
1022
- return self
1023
- . builtin_binary_op_return_ty ( op, lhs_ty, rhs_ty)
1024
- . unwrap_or_else ( || self . err_ty ( ) ) ;
1019
+ // HACK: `rhs_ty` is a general inference variable with no clue at all at this
1020
+ // point. Passing `lhs_ty` as both operands just to check if `lhs_ty` is a builtin
1021
+ // type applicable to `op`.
1022
+ let ret_ty = if self . is_builtin_binop ( & lhs_ty, & lhs_ty, op) {
1023
+ // Assume both operands are builtin so we can continue inference. No guarantee
1024
+ // on the correctness, rustc would complain as necessary lang items don't seem
1025
+ // to exist anyway.
1026
+ self . enforce_builtin_binop_types ( & lhs_ty, & rhs_ty, op)
1027
+ } else {
1028
+ self . err_ty ( )
1029
+ } ;
1030
+
1031
+ self . infer_expr_coerce ( rhs, & Expectation :: has_type ( rhs_ty) ) ;
1032
+
1033
+ return ret_ty;
1025
1034
}
1026
1035
} ;
1027
1036
@@ -1475,97 +1484,6 @@ impl<'a> InferenceContext<'a> {
1475
1484
indices
1476
1485
}
1477
1486
1478
- fn builtin_binary_op_return_ty ( & mut self , op : BinaryOp , lhs_ty : Ty , rhs_ty : Ty ) -> Option < Ty > {
1479
- let lhs_ty = self . resolve_ty_shallow ( & lhs_ty) ;
1480
- let rhs_ty = self . resolve_ty_shallow ( & rhs_ty) ;
1481
- match op {
1482
- BinaryOp :: LogicOp ( _) | BinaryOp :: CmpOp ( _) => {
1483
- Some ( TyKind :: Scalar ( Scalar :: Bool ) . intern ( Interner ) )
1484
- }
1485
- BinaryOp :: Assignment { .. } => Some ( TyBuilder :: unit ( ) ) ,
1486
- BinaryOp :: ArithOp ( ArithOp :: Shl | ArithOp :: Shr ) => {
1487
- // all integer combinations are valid here
1488
- if matches ! (
1489
- lhs_ty. kind( Interner ) ,
1490
- TyKind :: Scalar ( Scalar :: Int ( _) | Scalar :: Uint ( _) )
1491
- | TyKind :: InferenceVar ( _, TyVariableKind :: Integer )
1492
- ) && matches ! (
1493
- rhs_ty. kind( Interner ) ,
1494
- TyKind :: Scalar ( Scalar :: Int ( _) | Scalar :: Uint ( _) )
1495
- | TyKind :: InferenceVar ( _, TyVariableKind :: Integer )
1496
- ) {
1497
- Some ( lhs_ty)
1498
- } else {
1499
- None
1500
- }
1501
- }
1502
- BinaryOp :: ArithOp ( _) => match ( lhs_ty. kind ( Interner ) , rhs_ty. kind ( Interner ) ) {
1503
- // (int, int) | (uint, uint) | (float, float)
1504
- ( TyKind :: Scalar ( Scalar :: Int ( _) ) , TyKind :: Scalar ( Scalar :: Int ( _) ) )
1505
- | ( TyKind :: Scalar ( Scalar :: Uint ( _) ) , TyKind :: Scalar ( Scalar :: Uint ( _) ) )
1506
- | ( TyKind :: Scalar ( Scalar :: Float ( _) ) , TyKind :: Scalar ( Scalar :: Float ( _) ) ) => {
1507
- Some ( rhs_ty)
1508
- }
1509
- // ({int}, int) | ({int}, uint)
1510
- (
1511
- TyKind :: InferenceVar ( _, TyVariableKind :: Integer ) ,
1512
- TyKind :: Scalar ( Scalar :: Int ( _) | Scalar :: Uint ( _) ) ,
1513
- ) => Some ( rhs_ty) ,
1514
- // (int, {int}) | (uint, {int})
1515
- (
1516
- TyKind :: Scalar ( Scalar :: Int ( _) | Scalar :: Uint ( _) ) ,
1517
- TyKind :: InferenceVar ( _, TyVariableKind :: Integer ) ,
1518
- ) => Some ( lhs_ty) ,
1519
- // ({float} | float)
1520
- (
1521
- TyKind :: InferenceVar ( _, TyVariableKind :: Float ) ,
1522
- TyKind :: Scalar ( Scalar :: Float ( _) ) ,
1523
- ) => Some ( rhs_ty) ,
1524
- // (float, {float})
1525
- (
1526
- TyKind :: Scalar ( Scalar :: Float ( _) ) ,
1527
- TyKind :: InferenceVar ( _, TyVariableKind :: Float ) ,
1528
- ) => Some ( lhs_ty) ,
1529
- // ({int}, {int}) | ({float}, {float})
1530
- (
1531
- TyKind :: InferenceVar ( _, TyVariableKind :: Integer ) ,
1532
- TyKind :: InferenceVar ( _, TyVariableKind :: Integer ) ,
1533
- )
1534
- | (
1535
- TyKind :: InferenceVar ( _, TyVariableKind :: Float ) ,
1536
- TyKind :: InferenceVar ( _, TyVariableKind :: Float ) ,
1537
- ) => Some ( rhs_ty) ,
1538
- _ => None ,
1539
- } ,
1540
- }
1541
- }
1542
-
1543
- fn builtin_binary_op_rhs_expectation ( & mut self , op : BinaryOp , lhs_ty : Ty ) -> Option < Ty > {
1544
- Some ( match op {
1545
- BinaryOp :: LogicOp ( ..) => TyKind :: Scalar ( Scalar :: Bool ) . intern ( Interner ) ,
1546
- BinaryOp :: Assignment { op : None } => {
1547
- stdx:: never!( "Simple assignment operator is not binary op." ) ;
1548
- return None ;
1549
- }
1550
- BinaryOp :: CmpOp ( CmpOp :: Eq { .. } ) => match self
1551
- . resolve_ty_shallow ( & lhs_ty)
1552
- . kind ( Interner )
1553
- {
1554
- TyKind :: Scalar ( _) | TyKind :: Str => lhs_ty,
1555
- TyKind :: InferenceVar ( _, TyVariableKind :: Integer | TyVariableKind :: Float ) => lhs_ty,
1556
- _ => return None ,
1557
- } ,
1558
- BinaryOp :: ArithOp ( ArithOp :: Shl | ArithOp :: Shr ) => return None ,
1559
- BinaryOp :: CmpOp ( CmpOp :: Ord { .. } )
1560
- | BinaryOp :: Assignment { op : Some ( _) }
1561
- | BinaryOp :: ArithOp ( _) => match self . resolve_ty_shallow ( & lhs_ty) . kind ( Interner ) {
1562
- TyKind :: Scalar ( Scalar :: Int ( _) | Scalar :: Uint ( _) | Scalar :: Float ( _) ) => lhs_ty,
1563
- TyKind :: InferenceVar ( _, TyVariableKind :: Integer | TyVariableKind :: Float ) => lhs_ty,
1564
- _ => return None ,
1565
- } ,
1566
- } )
1567
- }
1568
-
1569
1487
/// Dereferences a single level of immutable referencing.
1570
1488
fn deref_ty_if_possible ( & mut self , ty : & Ty ) -> Ty {
1571
1489
let ty = self . resolve_ty_shallow ( ty) ;
0 commit comments