diff options
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 87 |
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 | 530 | fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty { |
531 | // always returns a boolean | ||
532 | fn 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 | |||
567 | fn 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 | }, |