aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/op.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/op.rs')
-rw-r--r--crates/hir_ty/src/op.rs66
1 files changed, 35 insertions, 31 deletions
diff --git a/crates/hir_ty/src/op.rs b/crates/hir_ty/src/op.rs
index bb9b8bbfc..527c5cbbd 100644
--- a/crates/hir_ty/src/op.rs
+++ b/crates/hir_ty/src/op.rs
@@ -2,51 +2,55 @@
2use chalk_ir::TyVariableKind; 2use chalk_ir::TyVariableKind;
3use hir_def::expr::{ArithOp, BinaryOp, CmpOp}; 3use hir_def::expr::{ArithOp, BinaryOp, CmpOp};
4 4
5use crate::{Scalar, Ty}; 5use crate::{Interner, Scalar, Ty, TyKind};
6 6
7pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, 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::Scalar(Scalar::Bool), 9 BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
10 BinaryOp::Assignment { .. } => Ty::unit(), 10 BinaryOp::Assignment { .. } => Ty::unit(),
11 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => match lhs_ty { 11 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => {
12 Ty::Scalar(Scalar::Int(_)) 12 match lhs_ty.interned(&Interner) {
13 | Ty::Scalar(Scalar::Uint(_)) 13 TyKind::Scalar(Scalar::Int(_))
14 | Ty::Scalar(Scalar::Float(_)) => lhs_ty, 14 | TyKind::Scalar(Scalar::Uint(_))
15 Ty::InferenceVar(_, TyVariableKind::Integer) 15 | TyKind::Scalar(Scalar::Float(_)) => lhs_ty,
16 | Ty::InferenceVar(_, TyVariableKind::Float) => lhs_ty, 16 TyKind::InferenceVar(_, TyVariableKind::Integer)
17 _ => Ty::Unknown, 17 | TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty,
18 }, 18 _ => TyKind::Unknown.intern(&Interner),
19 BinaryOp::ArithOp(_) => match rhs_ty { 19 }
20 Ty::Scalar(Scalar::Int(_)) 20 }
21 | Ty::Scalar(Scalar::Uint(_)) 21 BinaryOp::ArithOp(_) => match rhs_ty.interned(&Interner) {
22 | Ty::Scalar(Scalar::Float(_)) => rhs_ty, 22 TyKind::Scalar(Scalar::Int(_))
23 Ty::InferenceVar(_, TyVariableKind::Integer) 23 | TyKind::Scalar(Scalar::Uint(_))
24 | Ty::InferenceVar(_, TyVariableKind::Float) => rhs_ty, 24 | TyKind::Scalar(Scalar::Float(_)) => rhs_ty,
25 _ => Ty::Unknown, 25 TyKind::InferenceVar(_, TyVariableKind::Integer)
26 | TyKind::InferenceVar(_, TyVariableKind::Float) => rhs_ty,
27 _ => TyKind::Unknown.intern(&Interner),
26 }, 28 },
27 } 29 }
28} 30}
29 31
30pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { 32pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
31 match op { 33 match op {
32 BinaryOp::LogicOp(..) => Ty::Scalar(Scalar::Bool), 34 BinaryOp::LogicOp(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
33 BinaryOp::Assignment { op: None } => lhs_ty, 35 BinaryOp::Assignment { op: None } => lhs_ty,
34 BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty { 36 BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty.interned(&Interner) {
35 Ty::Scalar(_) | Ty::Str => lhs_ty, 37 TyKind::Scalar(_) | TyKind::Str => lhs_ty,
36 Ty::InferenceVar(_, TyVariableKind::Integer) 38 TyKind::InferenceVar(_, TyVariableKind::Integer)
37 | Ty::InferenceVar(_, TyVariableKind::Float) => lhs_ty, 39 | TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty,
38 _ => Ty::Unknown, 40 _ => TyKind::Unknown.intern(&Interner),
39 }, 41 },
40 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => Ty::Unknown, 42 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => {
43 TyKind::Unknown.intern(&Interner)
44 }
41 BinaryOp::CmpOp(CmpOp::Ord { .. }) 45 BinaryOp::CmpOp(CmpOp::Ord { .. })
42 | BinaryOp::Assignment { op: Some(_) } 46 | BinaryOp::Assignment { op: Some(_) }
43 | BinaryOp::ArithOp(_) => match lhs_ty { 47 | BinaryOp::ArithOp(_) => match lhs_ty.interned(&Interner) {
44 Ty::Scalar(Scalar::Int(_)) 48 TyKind::Scalar(Scalar::Int(_))
45 | Ty::Scalar(Scalar::Uint(_)) 49 | TyKind::Scalar(Scalar::Uint(_))
46 | Ty::Scalar(Scalar::Float(_)) => lhs_ty, 50 | TyKind::Scalar(Scalar::Float(_)) => lhs_ty,
47 Ty::InferenceVar(_, TyVariableKind::Integer) 51 TyKind::InferenceVar(_, TyVariableKind::Integer)
48 | Ty::InferenceVar(_, TyVariableKind::Float) => lhs_ty, 52 | TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty,
49 _ => Ty::Unknown, 53 _ => TyKind::Unknown.intern(&Interner),
50 }, 54 },
51 } 55 }
52} 56}