From 7e5a186c1fe585aac95019addc963bf74cb112ae Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 17 Aug 2019 17:42:41 +0300 Subject: Introduce separate hir::BinaryOp Unlike ast::BinOp, it has significantly more structure to it, so it's easier to, say, handle all assignment-like operations in the same way. --- crates/ra_hir/src/ty/infer.rs | 4 +-- crates/ra_hir/src/ty/op.rs | 84 +++++++++++-------------------------------- 2 files changed, 21 insertions(+), 67 deletions(-) (limited to 'crates/ra_hir/src/ty') diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 675df4a22..33bfd0952 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -1265,9 +1265,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { Expr::BinaryOp { lhs, rhs, op } => match op { Some(op) => { let lhs_expectation = match op { - BinaryOp::BooleanAnd | BinaryOp::BooleanOr => { - Expectation::has_type(Ty::simple(TypeCtor::Bool)) - } + BinaryOp::LogicOp(..) => Expectation::has_type(Ty::simple(TypeCtor::Bool)), _ => Expectation::none(), }; let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); diff --git a/crates/ra_hir/src/ty/op.rs b/crates/ra_hir/src/ty/op.rs index 9ba868298..1d089f1b0 100644 --- a/crates/ra_hir/src/ty/op.rs +++ b/crates/ra_hir/src/ty/op.rs @@ -1,37 +1,14 @@ use super::{InferTy, Ty, TypeCtor}; -use crate::{expr::BinaryOp, ty::ApplicationTy}; +use crate::{ + expr::{BinaryOp, CmpOp}, + ty::ApplicationTy, +}; pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty { match op { - BinaryOp::BooleanOr - | BinaryOp::BooleanAnd - | BinaryOp::EqualityTest - | BinaryOp::NegatedEqualityTest - | BinaryOp::LesserEqualTest - | BinaryOp::GreaterEqualTest - | BinaryOp::LesserTest - | BinaryOp::GreaterTest => Ty::simple(TypeCtor::Bool), - BinaryOp::Assignment - | BinaryOp::AddAssign - | BinaryOp::SubAssign - | BinaryOp::DivAssign - | BinaryOp::MulAssign - | BinaryOp::RemAssign - | BinaryOp::ShrAssign - | BinaryOp::ShlAssign - | BinaryOp::BitAndAssign - | BinaryOp::BitOrAssign - | BinaryOp::BitXorAssign => Ty::unit(), - BinaryOp::Addition - | BinaryOp::Subtraction - | BinaryOp::Multiplication - | BinaryOp::Division - | BinaryOp::Remainder - | BinaryOp::LeftShift - | BinaryOp::RightShift - | BinaryOp::BitwiseAnd - | BinaryOp::BitwiseOr - | BinaryOp::BitwiseXor => match rhs_ty { + BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::simple(TypeCtor::Bool), + BinaryOp::Assignment { .. } => Ty::unit(), + BinaryOp::ArithOp(_) => match rhs_ty { Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { TypeCtor::Int(..) | TypeCtor::Float(..) => rhs_ty, _ => Ty::Unknown, @@ -39,14 +16,15 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty { Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => rhs_ty, _ => Ty::Unknown, }, - BinaryOp::RangeRightOpen | BinaryOp::RangeRightClosed => Ty::Unknown, } } pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { match op { - BinaryOp::BooleanAnd | BinaryOp::BooleanOr => Ty::simple(TypeCtor::Bool), - BinaryOp::Assignment | BinaryOp::EqualityTest => match lhs_ty { + BinaryOp::LogicOp(..) => Ty::simple(TypeCtor::Bool), + BinaryOp::Assignment { op: None } + | BinaryOp::CmpOp(CmpOp::Equal) + | BinaryOp::CmpOp(CmpOp::NotEqual) => match lhs_ty { Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { TypeCtor::Int(..) | TypeCtor::Float(..) @@ -58,37 +36,15 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, _ => Ty::Unknown, }, - BinaryOp::LesserEqualTest - | BinaryOp::GreaterEqualTest - | BinaryOp::LesserTest - | BinaryOp::GreaterTest - | BinaryOp::AddAssign - | BinaryOp::SubAssign - | BinaryOp::DivAssign - | BinaryOp::MulAssign - | BinaryOp::RemAssign - | BinaryOp::ShrAssign - | BinaryOp::ShlAssign - | BinaryOp::BitAndAssign - | BinaryOp::BitOrAssign - | BinaryOp::BitXorAssign - | BinaryOp::Addition - | BinaryOp::Subtraction - | BinaryOp::Multiplication - | BinaryOp::Division - | BinaryOp::Remainder - | BinaryOp::LeftShift - | BinaryOp::RightShift - | BinaryOp::BitwiseAnd - | BinaryOp::BitwiseOr - | BinaryOp::BitwiseXor => match lhs_ty { - Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { - TypeCtor::Int(..) | TypeCtor::Float(..) => lhs_ty, + BinaryOp::CmpOp(_) | BinaryOp::Assignment { op: Some(_) } | BinaryOp::ArithOp(_) => { + match lhs_ty { + Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { + TypeCtor::Int(..) | TypeCtor::Float(..) => lhs_ty, + _ => Ty::Unknown, + }, + Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, _ => Ty::Unknown, - }, - Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, - _ => Ty::Unknown, - }, - _ => Ty::Unknown, + } + } } } -- cgit v1.2.3 From b082cd679ad1ae7646d03261bcccda435443365c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 17 Aug 2019 17:51:01 +0300 Subject: normalize ordering ops --- crates/ra_hir/src/ty/op.rs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'crates/ra_hir/src/ty') diff --git a/crates/ra_hir/src/ty/op.rs b/crates/ra_hir/src/ty/op.rs index 1d089f1b0..1b30a5b9b 100644 --- a/crates/ra_hir/src/ty/op.rs +++ b/crates/ra_hir/src/ty/op.rs @@ -22,29 +22,29 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty { pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { match op { BinaryOp::LogicOp(..) => Ty::simple(TypeCtor::Bool), - BinaryOp::Assignment { op: None } - | BinaryOp::CmpOp(CmpOp::Equal) - | BinaryOp::CmpOp(CmpOp::NotEqual) => match lhs_ty { - Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { - TypeCtor::Int(..) - | TypeCtor::Float(..) - | TypeCtor::Str - | TypeCtor::Char - | TypeCtor::Bool => lhs_ty, - _ => Ty::Unknown, - }, - Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, - _ => Ty::Unknown, - }, - BinaryOp::CmpOp(_) | BinaryOp::Assignment { op: Some(_) } | BinaryOp::ArithOp(_) => { + BinaryOp::Assignment { op: None } | BinaryOp::CmpOp(CmpOp::Eq { negated: _ }) => { match lhs_ty { Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { - TypeCtor::Int(..) | TypeCtor::Float(..) => lhs_ty, + TypeCtor::Int(..) + | TypeCtor::Float(..) + | TypeCtor::Str + | TypeCtor::Char + | TypeCtor::Bool => lhs_ty, _ => Ty::Unknown, }, Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, _ => Ty::Unknown, } } + BinaryOp::CmpOp(CmpOp::Ord { .. }) + | BinaryOp::Assignment { op: Some(_) } + | BinaryOp::ArithOp(_) => match lhs_ty { + Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { + TypeCtor::Int(..) | TypeCtor::Float(..) => lhs_ty, + _ => Ty::Unknown, + }, + Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, + _ => Ty::Unknown, + }, } } -- cgit v1.2.3 From 189d879659f4e44c3343023d6455bed7cdf0e7c9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 17 Aug 2019 18:05:20 +0300 Subject: implement initial type inference for index expressions --- crates/ra_hir/src/ty/infer.rs | 6 ++++++ crates/ra_hir/src/ty/tests.rs | 14 ++++++++++++++ 2 files changed, 20 insertions(+) (limited to 'crates/ra_hir/src/ty') diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 33bfd0952..cca59538a 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -1279,6 +1279,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { } _ => Ty::Unknown, }, + Expr::Index { base, index } => { + let _base_ty = self.infer_expr(*base, &Expectation::none()); + let _index_ty = self.infer_expr(*index, &Expectation::none()); + // FIXME: use `std::ops::Index::Output` to figure out the real return type + Ty::Unknown + } Expr::Tuple { exprs } => { let mut ty_vec = Vec::with_capacity(exprs.len()); for arg in exprs.iter() { diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 28727bb18..6c2d857bc 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs @@ -2655,6 +2655,20 @@ fn test() -> u64 { ); } +#[test] +fn indexing_arrays() { + assert_snapshot_matches!( + infer("fn main() { &mut [9][2]; }"), + @r###" +[10; 26) '{ &mut...[2]; }': () +[12; 23) '&mut [9][2]': &mut {unknown} +[17; 20) '[9]': [i32;_] +[17; 23) '[9][2]': {unknown} +[18; 19) '9': i32 +[21; 22) '2': i32"### + ) +} + #[test] fn infer_macros_expanded() { assert_snapshot_matches!( -- cgit v1.2.3