aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs4
-rw-r--r--crates/ra_hir_ty/src/op.rs15
-rw-r--r--crates/ra_hir_ty/src/tests/simple.rs21
3 files changed, 35 insertions, 5 deletions
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index d6a17e469..31259a01d 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -386,11 +386,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
386 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); 386 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
387 // FIXME: find implementation of trait corresponding to operation 387 // FIXME: find implementation of trait corresponding to operation
388 // symbol and resolve associated `Output` type 388 // symbol and resolve associated `Output` type
389 let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty); 389 let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty.clone());
390 let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation)); 390 let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation));
391 391
392 // FIXME: similar as above, return ty is often associated trait type 392 // FIXME: similar as above, return ty is often associated trait type
393 op::binary_op_return_ty(*op, rhs_ty) 393 op::binary_op_return_ty(*op, lhs_ty, rhs_ty)
394 } 394 }
395 _ => Ty::Unknown, 395 _ => Ty::Unknown,
396 }, 396 },
diff --git a/crates/ra_hir_ty/src/op.rs b/crates/ra_hir_ty/src/op.rs
index 09c47a76d..ae253ca04 100644
--- a/crates/ra_hir_ty/src/op.rs
+++ b/crates/ra_hir_ty/src/op.rs
@@ -1,13 +1,21 @@
1//! FIXME: write short doc here 1//! Helper functions for binary operator type inference.
2use hir_def::expr::{BinaryOp, CmpOp}; 2use hir_def::expr::{ArithOp, BinaryOp, CmpOp};
3 3
4use super::{InferTy, Ty, TypeCtor}; 4use super::{InferTy, Ty, TypeCtor};
5use crate::ApplicationTy; 5use crate::ApplicationTy;
6 6
7pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty { 7pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
8 match op { 8 match op {
9 BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::simple(TypeCtor::Bool), 9 BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::simple(TypeCtor::Bool),
10 BinaryOp::Assignment { .. } => Ty::unit(), 10 BinaryOp::Assignment { .. } => Ty::unit(),
11 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => match lhs_ty {
12 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
13 TypeCtor::Int(..) | TypeCtor::Float(..) => lhs_ty,
14 _ => Ty::Unknown,
15 },
16 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty,
17 _ => Ty::Unknown,
18 },
11 BinaryOp::ArithOp(_) => match rhs_ty { 19 BinaryOp::ArithOp(_) => match rhs_ty {
12 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { 20 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
13 TypeCtor::Int(..) | TypeCtor::Float(..) => rhs_ty, 21 TypeCtor::Int(..) | TypeCtor::Float(..) => rhs_ty,
@@ -36,6 +44,7 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
36 _ => Ty::Unknown, 44 _ => Ty::Unknown,
37 } 45 }
38 } 46 }
47 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => Ty::Unknown,
39 BinaryOp::CmpOp(CmpOp::Ord { .. }) 48 BinaryOp::CmpOp(CmpOp::Ord { .. })
40 | BinaryOp::Assignment { op: Some(_) } 49 | BinaryOp::Assignment { op: Some(_) }
41 | BinaryOp::ArithOp(_) => match lhs_ty { 50 | BinaryOp::ArithOp(_) => match lhs_ty {
diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs
index f7e042c12..b7204ec00 100644
--- a/crates/ra_hir_ty/src/tests/simple.rs
+++ b/crates/ra_hir_ty/src/tests/simple.rs
@@ -614,6 +614,27 @@ fn test() -> bool {
614} 614}
615 615
616#[test] 616#[test]
617fn infer_shift_op() {
618 assert_snapshot!(
619 infer(r#"
620fn test() {
621 1u32 << 5u8;
622 1u32 >> 5u8;
623}
624"#),
625 @r###"
626 [11; 48) '{ ...5u8; }': ()
627 [17; 21) '1u32': u32
628 [17; 28) '1u32 << 5u8': u32
629 [25; 28) '5u8': u8
630 [34; 38) '1u32': u32
631 [34; 45) '1u32 >> 5u8': u32
632 [42; 45) '5u8': u8
633 "###
634 );
635}
636
637#[test]
617fn infer_field_autoderef() { 638fn infer_field_autoderef() {
618 assert_snapshot!( 639 assert_snapshot!(
619 infer(r#" 640 infer(r#"