aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r--crates/ra_hir/src/ty.rs87
1 files changed, 74 insertions, 13 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index bba8527b7..7827e82c4 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -527,9 +527,7 @@ struct InferenceContext<'a, D: HirDatabase> {
527 return_ty: Ty, 527 return_ty: Ty,
528} 528}
529 529
530// helper function that determines whether a binary operator 530fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty {
531// always returns a boolean
532fn is_boolean_operator(op: BinaryOp) -> bool {
533 match op { 531 match op {
534 BinaryOp::BooleanOr 532 BinaryOp::BooleanOr
535 | BinaryOp::BooleanAnd 533 | BinaryOp::BooleanAnd
@@ -537,7 +535,70 @@ fn is_boolean_operator(op: BinaryOp) -> bool {
537 | BinaryOp::LesserEqualTest 535 | BinaryOp::LesserEqualTest
538 | BinaryOp::GreaterEqualTest 536 | BinaryOp::GreaterEqualTest
539 | BinaryOp::LesserTest 537 | BinaryOp::LesserTest
540 | BinaryOp::GreaterTest => true, 538 | BinaryOp::GreaterTest => Ty::Bool,
539 BinaryOp::Assignment
540 | BinaryOp::AddAssign
541 | BinaryOp::SubAssign
542 | BinaryOp::DivAssign
543 | BinaryOp::MulAssign
544 | BinaryOp::RemAssign
545 | BinaryOp::ShrAssign
546 | BinaryOp::ShlAssign
547 | BinaryOp::BitAndAssign
548 | BinaryOp::BitOrAssign
549 | BinaryOp::BitXorAssign => Ty::unit(),
550 BinaryOp::Addition
551 | BinaryOp::Subtraction
552 | BinaryOp::Multiplication
553 | BinaryOp::Division
554 | BinaryOp::Remainder
555 | BinaryOp::LeftShift
556 | BinaryOp::RightShift
557 | BinaryOp::BitwiseAnd
558 | BinaryOp::BitwiseOr
559 | BinaryOp::BitwiseXor => match rhs_ty {
560 Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) => rhs_ty,
561 _ => Ty::Unknown,
562 },
563 BinaryOp::RangeRightOpen | BinaryOp::RangeRightClosed => Ty::Unknown,
564 }
565}
566
567fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
568 match op {
569 BinaryOp::BooleanAnd | BinaryOp::BooleanOr => Ty::Bool,
570 BinaryOp::Assignment | BinaryOp::EqualityTest => match lhs_ty {
571 Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) | Ty::Str | Ty::Char | Ty::Bool => lhs_ty,
572 _ => Ty::Unknown,
573 },
574 BinaryOp::LesserEqualTest
575 | BinaryOp::GreaterEqualTest
576 | BinaryOp::LesserTest
577 | BinaryOp::GreaterTest
578 | BinaryOp::AddAssign
579 | BinaryOp::SubAssign
580 | BinaryOp::DivAssign
581 | BinaryOp::MulAssign
582 | BinaryOp::RemAssign
583 | BinaryOp::ShrAssign
584 | BinaryOp::ShlAssign
585 | BinaryOp::BitAndAssign
586 | BinaryOp::BitOrAssign
587 | BinaryOp::BitXorAssign
588 | BinaryOp::Addition
589 | BinaryOp::Subtraction
590 | BinaryOp::Multiplication
591 | BinaryOp::Division
592 | BinaryOp::Remainder
593 | BinaryOp::LeftShift
594 | BinaryOp::RightShift
595 | BinaryOp::BitwiseAnd
596 | BinaryOp::BitwiseOr
597 | BinaryOp::BitwiseXor => match lhs_ty {
598 Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) => lhs_ty,
599 _ => Ty::Unknown,
600 },
601 _ => Ty::Unknown,
541 } 602 }
542} 603}
543 604
@@ -889,20 +950,20 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
889 } 950 }
890 Expr::BinaryOp { lhs, rhs, op } => match op { 951 Expr::BinaryOp { lhs, rhs, op } => match op {
891 Some(op) => { 952 Some(op) => {
892 let subtype_expectation = match op { 953 let lhs_expectation = match op {
893 BinaryOp::BooleanAnd | BinaryOp::BooleanOr => { 954 BinaryOp::BooleanAnd | BinaryOp::BooleanOr => {
894 Expectation::has_type(Ty::Bool) 955 Expectation::has_type(Ty::Bool)
895 } 956 }
896 _ => Expectation::none(), 957 _ => Expectation::none(),
897 }; 958 };
898 let _lhs_ty = self.infer_expr(*lhs, &subtype_expectation)?; 959 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation)?;
899 let _rhs_ty = self.infer_expr(*rhs, &subtype_expectation)?; 960 // TODO: find implementation of trait corresponding to operation
900 961 // symbol and resolve associated `Output` type
901 if is_boolean_operator(*op) { 962 let rhs_expectation = binary_op_rhs_expectation(*op, lhs_ty);
902 Ty::Bool 963 let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation))?;
903 } else { 964
904 Ty::Unknown 965 // TODO: similar as above, return ty is often associated trait type
905 } 966 binary_op_return_ty(*op, rhs_ty)
906 } 967 }
907 _ => Ty::Unknown, 968 _ => Ty::Unknown,
908 }, 969 },