diff options
Diffstat (limited to 'crates/ra_hir/src/ty/infer.rs')
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 264 |
1 files changed, 147 insertions, 117 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 735cdecb9..bf42befbb 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -38,7 +38,7 @@ use crate::{ | |||
38 | resolve::{Resolver, Resolution}, | 38 | resolve::{Resolver, Resolution}, |
39 | nameres::Namespace | 39 | nameres::Namespace |
40 | }; | 40 | }; |
41 | use super::{Ty, TypableDef, Substs, primitive, op}; | 41 | use super::{Ty, TypableDef, Substs, primitive, op, FnSig, ApplicationTy, TypeCtor}; |
42 | 42 | ||
43 | /// The entry point of type inference. | 43 | /// The entry point of type inference. |
44 | pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> { | 44 | pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> { |
@@ -237,29 +237,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
237 | match (&*ty1, &*ty2) { | 237 | match (&*ty1, &*ty2) { |
238 | (Ty::Unknown, ..) => true, | 238 | (Ty::Unknown, ..) => true, |
239 | (.., Ty::Unknown) => true, | 239 | (.., Ty::Unknown) => true, |
240 | (Ty::Int(t1), Ty::Int(t2)) => match (t1, t2) { | 240 | (Ty::Apply(a_ty1), Ty::Apply(a_ty2)) if a_ty1.ctor == a_ty2.ctor => { |
241 | (primitive::UncertainIntTy::Unknown, _) | 241 | self.unify_substs(&a_ty1.parameters, &a_ty2.parameters, depth + 1) |
242 | | (_, primitive::UncertainIntTy::Unknown) => true, | ||
243 | _ => t1 == t2, | ||
244 | }, | ||
245 | (Ty::Float(t1), Ty::Float(t2)) => match (t1, t2) { | ||
246 | (primitive::UncertainFloatTy::Unknown, _) | ||
247 | | (_, primitive::UncertainFloatTy::Unknown) => true, | ||
248 | _ => t1 == t2, | ||
249 | }, | ||
250 | (Ty::Bool, _) | (Ty::Str, _) | (Ty::Never, _) | (Ty::Char, _) => ty1 == ty2, | ||
251 | ( | ||
252 | Ty::Adt { def_id: def_id1, substs: substs1, .. }, | ||
253 | Ty::Adt { def_id: def_id2, substs: substs2, .. }, | ||
254 | ) if def_id1 == def_id2 => self.unify_substs(substs1, substs2, depth + 1), | ||
255 | (Ty::Slice(t1), Ty::Slice(t2)) => self.unify_inner(t1, t2, depth + 1), | ||
256 | (Ty::RawPtr(t1, m1), Ty::RawPtr(t2, m2)) if m1 == m2 => { | ||
257 | self.unify_inner(t1, t2, depth + 1) | ||
258 | } | ||
259 | (Ty::Ref(t1, m1), Ty::Ref(t2, m2)) if m1 == m2 => self.unify_inner(t1, t2, depth + 1), | ||
260 | (Ty::FnPtr(sig1), Ty::FnPtr(sig2)) if sig1 == sig2 => true, | ||
261 | (Ty::Tuple(ts1), Ty::Tuple(ts2)) if ts1.len() == ts2.len() => { | ||
262 | ts1.iter().zip(ts2.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth + 1)) | ||
263 | } | 242 | } |
264 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) | 243 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) |
265 | | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) | 244 | | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) |
@@ -298,8 +277,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
298 | fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { | 277 | fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { |
299 | match ty { | 278 | match ty { |
300 | Ty::Unknown => self.new_type_var(), | 279 | Ty::Unknown => self.new_type_var(), |
301 | Ty::Int(primitive::UncertainIntTy::Unknown) => self.new_integer_var(), | 280 | Ty::Apply(ApplicationTy { |
302 | Ty::Float(primitive::UncertainFloatTy::Unknown) => self.new_float_var(), | 281 | ctor: TypeCtor::Int(primitive::UncertainIntTy::Unknown), |
282 | .. | ||
283 | }) => self.new_integer_var(), | ||
284 | Ty::Apply(ApplicationTy { | ||
285 | ctor: TypeCtor::Float(primitive::UncertainFloatTy::Unknown), | ||
286 | .. | ||
287 | }) => self.new_float_var(), | ||
303 | _ => ty, | 288 | _ => ty, |
304 | } | 289 | } |
305 | } | 290 | } |
@@ -610,12 +595,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
610 | Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Missing => false, | 595 | Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Missing => false, |
611 | }; | 596 | }; |
612 | if is_non_ref_pat { | 597 | if is_non_ref_pat { |
613 | while let Ty::Ref(inner, mutability) = expected { | 598 | while let Some((inner, mutability)) = expected.as_reference() { |
614 | expected = inner; | 599 | expected = inner; |
615 | default_bm = match default_bm { | 600 | default_bm = match default_bm { |
616 | BindingMode::Move => BindingMode::Ref(*mutability), | 601 | BindingMode::Move => BindingMode::Ref(mutability), |
617 | BindingMode::Ref(Mutability::Shared) => BindingMode::Ref(Mutability::Shared), | 602 | BindingMode::Ref(Mutability::Shared) => BindingMode::Ref(Mutability::Shared), |
618 | BindingMode::Ref(Mutability::Mut) => BindingMode::Ref(*mutability), | 603 | BindingMode::Ref(Mutability::Mut) => BindingMode::Ref(mutability), |
619 | } | 604 | } |
620 | } | 605 | } |
621 | } else if let Pat::Ref { .. } = &body[pat] { | 606 | } else if let Pat::Ref { .. } = &body[pat] { |
@@ -631,8 +616,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
631 | 616 | ||
632 | let ty = match &body[pat] { | 617 | let ty = match &body[pat] { |
633 | Pat::Tuple(ref args) => { | 618 | Pat::Tuple(ref args) => { |
634 | let expectations = match *expected { | 619 | let expectations = match expected.as_tuple() { |
635 | Ty::Tuple(ref tuple_args) => &**tuple_args, | 620 | Some(parameters) => &*parameters.0, |
636 | _ => &[], | 621 | _ => &[], |
637 | }; | 622 | }; |
638 | let expectations_iter = expectations.iter().chain(repeat(&Ty::Unknown)); | 623 | let expectations_iter = expectations.iter().chain(repeat(&Ty::Unknown)); |
@@ -644,20 +629,20 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
644 | .collect::<Vec<_>>() | 629 | .collect::<Vec<_>>() |
645 | .into(); | 630 | .into(); |
646 | 631 | ||
647 | Ty::Tuple(inner_tys) | 632 | Ty::apply(TypeCtor::Tuple, Substs(inner_tys)) |
648 | } | 633 | } |
649 | Pat::Ref { pat, mutability } => { | 634 | Pat::Ref { pat, mutability } => { |
650 | let expectation = match *expected { | 635 | let expectation = match expected.as_reference() { |
651 | Ty::Ref(ref sub_ty, exp_mut) => { | 636 | Some((inner_ty, exp_mut)) => { |
652 | if *mutability != exp_mut { | 637 | if *mutability != exp_mut { |
653 | // TODO: emit type error? | 638 | // TODO: emit type error? |
654 | } | 639 | } |
655 | &**sub_ty | 640 | inner_ty |
656 | } | 641 | } |
657 | _ => &Ty::Unknown, | 642 | _ => &Ty::Unknown, |
658 | }; | 643 | }; |
659 | let subty = self.infer_pat(*pat, expectation, default_bm); | 644 | let subty = self.infer_pat(*pat, expectation, default_bm); |
660 | Ty::Ref(subty.into(), *mutability) | 645 | Ty::apply_one(TypeCtor::Ref(*mutability), subty.into()) |
661 | } | 646 | } |
662 | Pat::TupleStruct { path: ref p, args: ref subpats } => { | 647 | Pat::TupleStruct { path: ref p, args: ref subpats } => { |
663 | self.infer_tuple_struct_pat(p.as_ref(), subpats, expected, default_bm) | 648 | self.infer_tuple_struct_pat(p.as_ref(), subpats, expected, default_bm) |
@@ -684,7 +669,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
684 | let inner_ty = self.insert_type_vars_shallow(inner_ty); | 669 | let inner_ty = self.insert_type_vars_shallow(inner_ty); |
685 | 670 | ||
686 | let bound_ty = match mode { | 671 | let bound_ty = match mode { |
687 | BindingMode::Ref(mutability) => Ty::Ref(inner_ty.clone().into(), mutability), | 672 | BindingMode::Ref(mutability) => { |
673 | Ty::apply_one(TypeCtor::Ref(mutability), inner_ty.clone().into()) | ||
674 | } | ||
688 | BindingMode::Move => inner_ty.clone(), | 675 | BindingMode::Move => inner_ty.clone(), |
689 | }; | 676 | }; |
690 | let bound_ty = self.resolve_ty_as_possible(&mut vec![], bound_ty); | 677 | let bound_ty = self.resolve_ty_as_possible(&mut vec![], bound_ty); |
@@ -738,7 +725,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
738 | Expr::Missing => Ty::Unknown, | 725 | Expr::Missing => Ty::Unknown, |
739 | Expr::If { condition, then_branch, else_branch } => { | 726 | Expr::If { condition, then_branch, else_branch } => { |
740 | // if let is desugared to match, so this is always simple if | 727 | // if let is desugared to match, so this is always simple if |
741 | self.infer_expr(*condition, &Expectation::has_type(Ty::Bool)); | 728 | self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); |
742 | let then_ty = self.infer_expr(*then_branch, expected); | 729 | let then_ty = self.infer_expr(*then_branch, expected); |
743 | match else_branch { | 730 | match else_branch { |
744 | Some(else_branch) => { | 731 | Some(else_branch) => { |
@@ -755,11 +742,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
755 | Expr::Loop { body } => { | 742 | Expr::Loop { body } => { |
756 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 743 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
757 | // TODO handle break with value | 744 | // TODO handle break with value |
758 | Ty::Never | 745 | Ty::simple(TypeCtor::Never) |
759 | } | 746 | } |
760 | Expr::While { condition, body } => { | 747 | Expr::While { condition, body } => { |
761 | // while let is desugared to a match loop, so this is always simple while | 748 | // while let is desugared to a match loop, so this is always simple while |
762 | self.infer_expr(*condition, &Expectation::has_type(Ty::Bool)); | 749 | self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); |
763 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 750 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
764 | Ty::unit() | 751 | Ty::unit() |
765 | } | 752 | } |
@@ -789,14 +776,23 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
789 | Expr::Call { callee, args } => { | 776 | Expr::Call { callee, args } => { |
790 | let callee_ty = self.infer_expr(*callee, &Expectation::none()); | 777 | let callee_ty = self.infer_expr(*callee, &Expectation::none()); |
791 | let (param_tys, ret_ty) = match &callee_ty { | 778 | let (param_tys, ret_ty) = match &callee_ty { |
792 | Ty::FnPtr(sig) => (sig.params().to_vec(), sig.ret().clone()), | 779 | Ty::Apply(a_ty) => match a_ty.ctor { |
793 | Ty::FnDef { substs, def, .. } => { | 780 | TypeCtor::FnPtr => { |
794 | let sig = self.db.callable_item_signature(*def); | 781 | let sig = FnSig::from_fn_ptr_substs(&a_ty.parameters); |
795 | let ret_ty = sig.ret().clone().subst(&substs); | 782 | (sig.params().to_vec(), sig.ret().clone()) |
796 | let param_tys = | 783 | } |
797 | sig.params().iter().map(|ty| ty.clone().subst(&substs)).collect(); | 784 | TypeCtor::FnDef(def) => { |
798 | (param_tys, ret_ty) | 785 | let sig = self.db.callable_item_signature(def); |
799 | } | 786 | let ret_ty = sig.ret().clone().subst(&a_ty.parameters); |
787 | let param_tys = sig | ||
788 | .params() | ||
789 | .iter() | ||
790 | .map(|ty| ty.clone().subst(&a_ty.parameters)) | ||
791 | .collect(); | ||
792 | (param_tys, ret_ty) | ||
793 | } | ||
794 | _ => (Vec::new(), Ty::Unknown), | ||
795 | }, | ||
800 | _ => { | 796 | _ => { |
801 | // not callable | 797 | // not callable |
802 | // TODO report an error? | 798 | // TODO report an error? |
@@ -821,37 +817,49 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
821 | Some(func.generic_params(self.db)), | 817 | Some(func.generic_params(self.db)), |
822 | ) | 818 | ) |
823 | } | 819 | } |
824 | None => (Ty::Unknown, receiver_ty, None), | 820 | None => (receiver_ty, Ty::Unknown, None), |
825 | }; | 821 | }; |
826 | let substs = self.substs_for_method_call(def_generics, generic_args); | 822 | let substs = self.substs_for_method_call(def_generics, generic_args); |
827 | let method_ty = method_ty.apply_substs(substs); | 823 | let method_ty = method_ty.apply_substs(substs); |
828 | let method_ty = self.insert_type_vars(method_ty); | 824 | let method_ty = self.insert_type_vars(method_ty); |
829 | let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty { | 825 | let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty { |
830 | Ty::FnPtr(sig) => { | 826 | Ty::Apply(a_ty) => match a_ty.ctor { |
831 | if !sig.params().is_empty() { | 827 | TypeCtor::FnPtr => { |
832 | (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone()) | 828 | let sig = FnSig::from_fn_ptr_substs(&a_ty.parameters); |
833 | } else { | 829 | if !sig.params().is_empty() { |
834 | (Ty::Unknown, Vec::new(), sig.ret().clone()) | 830 | ( |
831 | sig.params()[0].clone(), | ||
832 | sig.params()[1..].to_vec(), | ||
833 | sig.ret().clone(), | ||
834 | ) | ||
835 | } else { | ||
836 | (Ty::Unknown, Vec::new(), sig.ret().clone()) | ||
837 | } | ||
835 | } | 838 | } |
836 | } | 839 | TypeCtor::FnDef(def) => { |
837 | Ty::FnDef { substs, def, .. } => { | 840 | let sig = self.db.callable_item_signature(def); |
838 | let sig = self.db.callable_item_signature(*def); | 841 | let ret_ty = sig.ret().clone().subst(&a_ty.parameters); |
839 | let ret_ty = sig.ret().clone().subst(&substs); | 842 | |
840 | 843 | if !sig.params().is_empty() { | |
841 | if !sig.params().is_empty() { | 844 | let mut params_iter = sig |
842 | let mut params_iter = | 845 | .params() |
843 | sig.params().iter().map(|ty| ty.clone().subst(&substs)); | 846 | .iter() |
844 | let receiver_ty = params_iter.next().unwrap(); | 847 | .map(|ty| ty.clone().subst(&a_ty.parameters)); |
845 | (receiver_ty, params_iter.collect(), ret_ty) | 848 | let receiver_ty = params_iter.next().unwrap(); |
846 | } else { | 849 | (receiver_ty, params_iter.collect(), ret_ty) |
847 | (Ty::Unknown, Vec::new(), ret_ty) | 850 | } else { |
851 | (Ty::Unknown, Vec::new(), ret_ty) | ||
852 | } | ||
848 | } | 853 | } |
849 | } | 854 | _ => (Ty::Unknown, Vec::new(), Ty::Unknown), |
855 | }, | ||
850 | _ => (Ty::Unknown, Vec::new(), Ty::Unknown), | 856 | _ => (Ty::Unknown, Vec::new(), Ty::Unknown), |
851 | }; | 857 | }; |
852 | // Apply autoref so the below unification works correctly | 858 | // Apply autoref so the below unification works correctly |
853 | let actual_receiver_ty = match expected_receiver_ty { | 859 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { |
854 | Ty::Ref(_, mutability) => Ty::Ref(Arc::new(derefed_receiver_ty), mutability), | 860 | Some((_, mutability)) => { |
861 | Ty::apply_one(TypeCtor::Ref(mutability), derefed_receiver_ty) | ||
862 | } | ||
855 | _ => derefed_receiver_ty, | 863 | _ => derefed_receiver_ty, |
856 | }; | 864 | }; |
857 | self.unify(&expected_receiver_ty, &actual_receiver_ty); | 865 | self.unify(&expected_receiver_ty, &actual_receiver_ty); |
@@ -875,7 +883,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
875 | let _pat_ty = self.infer_pat(pat, &input_ty, BindingMode::default()); | 883 | let _pat_ty = self.infer_pat(pat, &input_ty, BindingMode::default()); |
876 | } | 884 | } |
877 | if let Some(guard_expr) = arm.guard { | 885 | if let Some(guard_expr) = arm.guard { |
878 | self.infer_expr(guard_expr, &Expectation::has_type(Ty::Bool)); | 886 | self.infer_expr( |
887 | guard_expr, | ||
888 | &Expectation::has_type(Ty::simple(TypeCtor::Bool)), | ||
889 | ); | ||
879 | } | 890 | } |
880 | self.infer_expr(arm.expr, &expected); | 891 | self.infer_expr(arm.expr, &expected); |
881 | } | 892 | } |
@@ -887,19 +898,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
887 | let resolver = expr::resolver_for_expr(self.body.clone(), self.db, tgt_expr); | 898 | let resolver = expr::resolver_for_expr(self.body.clone(), self.db, tgt_expr); |
888 | self.infer_path_expr(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) | 899 | self.infer_path_expr(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) |
889 | } | 900 | } |
890 | Expr::Continue => Ty::Never, | 901 | Expr::Continue => Ty::simple(TypeCtor::Never), |
891 | Expr::Break { expr } => { | 902 | Expr::Break { expr } => { |
892 | if let Some(expr) = expr { | 903 | if let Some(expr) = expr { |
893 | // TODO handle break with value | 904 | // TODO handle break with value |
894 | self.infer_expr(*expr, &Expectation::none()); | 905 | self.infer_expr(*expr, &Expectation::none()); |
895 | } | 906 | } |
896 | Ty::Never | 907 | Ty::simple(TypeCtor::Never) |
897 | } | 908 | } |
898 | Expr::Return { expr } => { | 909 | Expr::Return { expr } => { |
899 | if let Some(expr) = expr { | 910 | if let Some(expr) = expr { |
900 | self.infer_expr(*expr, &Expectation::has_type(self.return_ty.clone())); | 911 | self.infer_expr(*expr, &Expectation::has_type(self.return_ty.clone())); |
901 | } | 912 | } |
902 | Ty::Never | 913 | Ty::simple(TypeCtor::Never) |
903 | } | 914 | } |
904 | Expr::StructLit { path, fields, spread } => { | 915 | Expr::StructLit { path, fields, spread } => { |
905 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 916 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
@@ -921,16 +932,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
921 | let ty = receiver_ty | 932 | let ty = receiver_ty |
922 | .autoderef(self.db) | 933 | .autoderef(self.db) |
923 | .find_map(|derefed_ty| match derefed_ty { | 934 | .find_map(|derefed_ty| match derefed_ty { |
924 | Ty::Tuple(fields) => { | 935 | Ty::Apply(a_ty) => match a_ty.ctor { |
925 | let i = name.to_string().parse::<usize>().ok(); | 936 | TypeCtor::Tuple => { |
926 | i.and_then(|i| fields.get(i).cloned()) | 937 | let i = name.to_string().parse::<usize>().ok(); |
927 | } | 938 | i.and_then(|i| a_ty.parameters.0.get(i).cloned()) |
928 | Ty::Adt { def_id: AdtDef::Struct(s), ref substs, .. } => { | 939 | } |
929 | s.field(self.db, name).map(|field| { | 940 | TypeCtor::Adt(AdtDef::Struct(s)) => { |
930 | self.write_field_resolution(tgt_expr, field); | 941 | s.field(self.db, name).map(|field| { |
931 | field.ty(self.db).subst(substs) | 942 | self.write_field_resolution(tgt_expr, field); |
932 | }) | 943 | field.ty(self.db).subst(&a_ty.parameters) |
933 | } | 944 | }) |
945 | } | ||
946 | _ => None, | ||
947 | }, | ||
934 | _ => None, | 948 | _ => None, |
935 | }) | 949 | }) |
936 | .unwrap_or(Ty::Unknown); | 950 | .unwrap_or(Ty::Unknown); |
@@ -947,18 +961,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
947 | cast_ty | 961 | cast_ty |
948 | } | 962 | } |
949 | Expr::Ref { expr, mutability } => { | 963 | Expr::Ref { expr, mutability } => { |
950 | let expectation = if let Ty::Ref(ref subty, expected_mutability) = expected.ty { | 964 | let expectation = |
951 | if expected_mutability == Mutability::Mut && *mutability == Mutability::Shared { | 965 | if let Some((exp_inner, exp_mutability)) = &expected.ty.as_reference() { |
952 | // TODO: throw type error - expected mut reference but found shared ref, | 966 | if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared { |
953 | // which cannot be coerced | 967 | // TODO: throw type error - expected mut reference but found shared ref, |
954 | } | 968 | // which cannot be coerced |
955 | Expectation::has_type((**subty).clone()) | 969 | } |
956 | } else { | 970 | Expectation::has_type(Ty::clone(exp_inner)) |
957 | Expectation::none() | 971 | } else { |
958 | }; | 972 | Expectation::none() |
973 | }; | ||
959 | // TODO reference coercions etc. | 974 | // TODO reference coercions etc. |
960 | let inner_ty = self.infer_expr(*expr, &expectation); | 975 | let inner_ty = self.infer_expr(*expr, &expectation); |
961 | Ty::Ref(Arc::new(inner_ty), *mutability) | 976 | Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) |
962 | } | 977 | } |
963 | Expr::UnaryOp { expr, op } => { | 978 | Expr::UnaryOp { expr, op } => { |
964 | let inner_ty = self.infer_expr(*expr, &Expectation::none()); | 979 | let inner_ty = self.infer_expr(*expr, &Expectation::none()); |
@@ -972,19 +987,27 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
972 | } | 987 | } |
973 | } | 988 | } |
974 | UnaryOp::Neg => { | 989 | UnaryOp::Neg => { |
975 | match inner_ty { | 990 | match &inner_ty { |
976 | Ty::Int(primitive::UncertainIntTy::Unknown) | 991 | Ty::Apply(a_ty) => match a_ty.ctor { |
977 | | Ty::Int(primitive::UncertainIntTy::Signed(..)) | 992 | TypeCtor::Int(primitive::UncertainIntTy::Unknown) |
978 | | Ty::Infer(InferTy::IntVar(..)) | 993 | | TypeCtor::Int(primitive::UncertainIntTy::Signed(..)) |
979 | | Ty::Infer(InferTy::FloatVar(..)) | 994 | | TypeCtor::Float(..) => inner_ty, |
980 | | Ty::Float(..) => inner_ty, | 995 | _ => Ty::Unknown, |
996 | }, | ||
997 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => { | ||
998 | inner_ty | ||
999 | } | ||
981 | // TODO: resolve ops::Neg trait | 1000 | // TODO: resolve ops::Neg trait |
982 | _ => Ty::Unknown, | 1001 | _ => Ty::Unknown, |
983 | } | 1002 | } |
984 | } | 1003 | } |
985 | UnaryOp::Not => { | 1004 | UnaryOp::Not => { |
986 | match inner_ty { | 1005 | match &inner_ty { |
987 | Ty::Bool | Ty::Int(_) | Ty::Infer(InferTy::IntVar(..)) => inner_ty, | 1006 | Ty::Apply(a_ty) => match a_ty.ctor { |
1007 | TypeCtor::Bool | TypeCtor::Int(_) => inner_ty, | ||
1008 | _ => Ty::Unknown, | ||
1009 | }, | ||
1010 | Ty::Infer(InferTy::IntVar(..)) => inner_ty, | ||
988 | // TODO: resolve ops::Not trait for inner_ty | 1011 | // TODO: resolve ops::Not trait for inner_ty |
989 | _ => Ty::Unknown, | 1012 | _ => Ty::Unknown, |
990 | } | 1013 | } |
@@ -995,7 +1018,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
995 | Some(op) => { | 1018 | Some(op) => { |
996 | let lhs_expectation = match op { | 1019 | let lhs_expectation = match op { |
997 | BinaryOp::BooleanAnd | BinaryOp::BooleanOr => { | 1020 | BinaryOp::BooleanAnd | BinaryOp::BooleanOr => { |
998 | Expectation::has_type(Ty::Bool) | 1021 | Expectation::has_type(Ty::simple(TypeCtor::Bool)) |
999 | } | 1022 | } |
1000 | _ => Expectation::none(), | 1023 | _ => Expectation::none(), |
1001 | }; | 1024 | }; |
@@ -1016,11 +1039,16 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1016 | ty_vec.push(self.infer_expr(*arg, &Expectation::none())); | 1039 | ty_vec.push(self.infer_expr(*arg, &Expectation::none())); |
1017 | } | 1040 | } |
1018 | 1041 | ||
1019 | Ty::Tuple(Arc::from(ty_vec)) | 1042 | Ty::apply(TypeCtor::Tuple, Substs(ty_vec.into())) |
1020 | } | 1043 | } |
1021 | Expr::Array { exprs } => { | 1044 | Expr::Array { exprs } => { |
1022 | let elem_ty = match &expected.ty { | 1045 | let elem_ty = match &expected.ty { |
1023 | Ty::Slice(inner) | Ty::Array(inner) => Ty::clone(&inner), | 1046 | Ty::Apply(a_ty) => match a_ty.ctor { |
1047 | TypeCtor::Slice | TypeCtor::Array => { | ||
1048 | Ty::clone(&a_ty.parameters.as_single()) | ||
1049 | } | ||
1050 | _ => self.new_type_var(), | ||
1051 | }, | ||
1024 | _ => self.new_type_var(), | 1052 | _ => self.new_type_var(), |
1025 | }; | 1053 | }; |
1026 | 1054 | ||
@@ -1028,21 +1056,23 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1028 | self.infer_expr(*expr, &Expectation::has_type(elem_ty.clone())); | 1056 | self.infer_expr(*expr, &Expectation::has_type(elem_ty.clone())); |
1029 | } | 1057 | } |
1030 | 1058 | ||
1031 | Ty::Array(Arc::new(elem_ty)) | 1059 | Ty::apply_one(TypeCtor::Array, elem_ty) |
1032 | } | 1060 | } |
1033 | Expr::Literal(lit) => match lit { | 1061 | Expr::Literal(lit) => match lit { |
1034 | Literal::Bool(..) => Ty::Bool, | 1062 | Literal::Bool(..) => Ty::simple(TypeCtor::Bool), |
1035 | Literal::String(..) => Ty::Ref(Arc::new(Ty::Str), Mutability::Shared), | 1063 | Literal::String(..) => { |
1064 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str)) | ||
1065 | } | ||
1036 | Literal::ByteString(..) => { | 1066 | Literal::ByteString(..) => { |
1037 | let byte_type = Arc::new(Ty::Int(primitive::UncertainIntTy::Unsigned( | 1067 | let byte_type = Ty::simple(TypeCtor::Int(primitive::UncertainIntTy::Unsigned( |
1038 | primitive::UintTy::U8, | 1068 | primitive::UintTy::U8, |
1039 | ))); | 1069 | ))); |
1040 | let slice_type = Arc::new(Ty::Slice(byte_type)); | 1070 | let slice_type = Ty::apply_one(TypeCtor::Slice, byte_type); |
1041 | Ty::Ref(slice_type, Mutability::Shared) | 1071 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), slice_type) |
1042 | } | 1072 | } |
1043 | Literal::Char(..) => Ty::Char, | 1073 | Literal::Char(..) => Ty::simple(TypeCtor::Char), |
1044 | Literal::Int(_v, ty) => Ty::Int(*ty), | 1074 | Literal::Int(_v, ty) => Ty::simple(TypeCtor::Int(*ty)), |
1045 | Literal::Float(_v, ty) => Ty::Float(*ty), | 1075 | Literal::Float(_v, ty) => Ty::simple(TypeCtor::Float(*ty)), |
1046 | }, | 1076 | }, |
1047 | }; | 1077 | }; |
1048 | // use a new type variable if we got Ty::Unknown here | 1078 | // use a new type variable if we got Ty::Unknown here |
@@ -1178,11 +1208,11 @@ impl InferTy { | |||
1178 | match self { | 1208 | match self { |
1179 | InferTy::TypeVar(..) => Ty::Unknown, | 1209 | InferTy::TypeVar(..) => Ty::Unknown, |
1180 | InferTy::IntVar(..) => { | 1210 | InferTy::IntVar(..) => { |
1181 | Ty::Int(primitive::UncertainIntTy::Signed(primitive::IntTy::I32)) | 1211 | Ty::simple(TypeCtor::Int(primitive::UncertainIntTy::Signed(primitive::IntTy::I32))) |
1182 | } | ||
1183 | InferTy::FloatVar(..) => { | ||
1184 | Ty::Float(primitive::UncertainFloatTy::Known(primitive::FloatTy::F64)) | ||
1185 | } | 1212 | } |
1213 | InferTy::FloatVar(..) => Ty::simple(TypeCtor::Float( | ||
1214 | primitive::UncertainFloatTy::Known(primitive::FloatTy::F64), | ||
1215 | )), | ||
1186 | } | 1216 | } |
1187 | } | 1217 | } |
1188 | } | 1218 | } |