diff options
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 63 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 26 |
2 files changed, 66 insertions, 23 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index cb59a6937..c25f3f34b 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -4,7 +4,6 @@ use std::iter::{repeat, repeat_with}; | |||
4 | use std::{mem, sync::Arc}; | 4 | use std::{mem, sync::Arc}; |
5 | 5 | ||
6 | use hir_def::{ | 6 | use hir_def::{ |
7 | builtin_type::Signedness, | ||
8 | expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, | 7 | expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, |
9 | path::{GenericArg, GenericArgs}, | 8 | path::{GenericArg, GenericArgs}, |
10 | resolver::resolver_for_expr, | 9 | resolver::resolver_for_expr, |
@@ -16,10 +15,11 @@ use test_utils::mark; | |||
16 | 15 | ||
17 | use crate::{ | 16 | use crate::{ |
18 | autoderef, method_resolution, op, | 17 | autoderef, method_resolution, op, |
18 | primitive::UintTy, | ||
19 | traits::{FnTrait, InEnvironment}, | 19 | traits::{FnTrait, InEnvironment}, |
20 | utils::{generics, variant_data, Generics}, | 20 | utils::{generics, variant_data, Generics}, |
21 | ApplicationTy, Binders, CallableDefId, InferTy, IntTy, Mutability, Obligation, OpaqueTyId, | 21 | ApplicationTy, Binders, CallableDefId, InferTy, Mutability, Obligation, OpaqueTyId, Rawness, |
22 | Rawness, Substs, TraitRef, Ty, TypeCtor, | 22 | Scalar, Substs, TraitRef, Ty, TypeCtor, |
23 | }; | 23 | }; |
24 | 24 | ||
25 | use super::{ | 25 | use super::{ |
@@ -120,7 +120,10 @@ impl<'a> InferenceContext<'a> { | |||
120 | Expr::Missing => Ty::Unknown, | 120 | Expr::Missing => Ty::Unknown, |
121 | Expr::If { condition, then_branch, else_branch } => { | 121 | Expr::If { condition, then_branch, else_branch } => { |
122 | // if let is desugared to match, so this is always simple if | 122 | // if let is desugared to match, so this is always simple if |
123 | self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); | 123 | self.infer_expr( |
124 | *condition, | ||
125 | &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))), | ||
126 | ); | ||
124 | 127 | ||
125 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); | 128 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); |
126 | let mut both_arms_diverge = Diverges::Always; | 129 | let mut both_arms_diverge = Diverges::Always; |
@@ -203,7 +206,10 @@ impl<'a> InferenceContext<'a> { | |||
203 | label: label.map(|label| self.body[label].name.clone()), | 206 | label: label.map(|label| self.body[label].name.clone()), |
204 | }); | 207 | }); |
205 | // while let is desugared to a match loop, so this is always simple while | 208 | // while let is desugared to a match loop, so this is always simple while |
206 | self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); | 209 | self.infer_expr( |
210 | *condition, | ||
211 | &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))), | ||
212 | ); | ||
207 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 213 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
208 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); | 214 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); |
209 | // the body may not run, so it diverging doesn't mean we diverge | 215 | // the body may not run, so it diverging doesn't mean we diverge |
@@ -321,7 +327,7 @@ impl<'a> InferenceContext<'a> { | |||
321 | if let Some(guard_expr) = arm.guard { | 327 | if let Some(guard_expr) = arm.guard { |
322 | self.infer_expr( | 328 | self.infer_expr( |
323 | guard_expr, | 329 | guard_expr, |
324 | &Expectation::has_type(Ty::simple(TypeCtor::Bool)), | 330 | &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))), |
325 | ); | 331 | ); |
326 | } | 332 | } |
327 | 333 | ||
@@ -534,10 +540,13 @@ impl<'a> InferenceContext<'a> { | |||
534 | match &inner_ty { | 540 | match &inner_ty { |
535 | // Fast path for builtins | 541 | // Fast path for builtins |
536 | Ty::Apply(ApplicationTy { | 542 | Ty::Apply(ApplicationTy { |
537 | ctor: TypeCtor::Int(IntTy { signedness: Signedness::Signed, .. }), | 543 | ctor: TypeCtor::Scalar(Scalar::Int(_)), |
544 | .. | ||
545 | }) | ||
546 | | Ty::Apply(ApplicationTy { | ||
547 | ctor: TypeCtor::Scalar(Scalar::Float(_)), | ||
538 | .. | 548 | .. |
539 | }) | 549 | }) |
540 | | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(_), .. }) | ||
541 | | Ty::Infer(InferTy::IntVar(..)) | 550 | | Ty::Infer(InferTy::IntVar(..)) |
542 | | Ty::Infer(InferTy::FloatVar(..)) => inner_ty, | 551 | | Ty::Infer(InferTy::FloatVar(..)) => inner_ty, |
543 | // Otherwise we resolve via the std::ops::Neg trait | 552 | // Otherwise we resolve via the std::ops::Neg trait |
@@ -548,8 +557,18 @@ impl<'a> InferenceContext<'a> { | |||
548 | UnaryOp::Not => { | 557 | UnaryOp::Not => { |
549 | match &inner_ty { | 558 | match &inner_ty { |
550 | // Fast path for builtins | 559 | // Fast path for builtins |
551 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. }) | 560 | Ty::Apply(ApplicationTy { |
552 | | Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(_), .. }) | 561 | ctor: TypeCtor::Scalar(Scalar::Bool), |
562 | .. | ||
563 | }) | ||
564 | | Ty::Apply(ApplicationTy { | ||
565 | ctor: TypeCtor::Scalar(Scalar::Int(_)), | ||
566 | .. | ||
567 | }) | ||
568 | | Ty::Apply(ApplicationTy { | ||
569 | ctor: TypeCtor::Scalar(Scalar::Uint(_)), | ||
570 | .. | ||
571 | }) | ||
553 | | Ty::Infer(InferTy::IntVar(..)) => inner_ty, | 572 | | Ty::Infer(InferTy::IntVar(..)) => inner_ty, |
554 | // Otherwise we resolve via the std::ops::Not trait | 573 | // Otherwise we resolve via the std::ops::Not trait |
555 | _ => self | 574 | _ => self |
@@ -561,7 +580,9 @@ impl<'a> InferenceContext<'a> { | |||
561 | Expr::BinaryOp { lhs, rhs, op } => match op { | 580 | Expr::BinaryOp { lhs, rhs, op } => match op { |
562 | Some(op) => { | 581 | Some(op) => { |
563 | let lhs_expectation = match op { | 582 | let lhs_expectation = match op { |
564 | BinaryOp::LogicOp(..) => Expectation::has_type(Ty::simple(TypeCtor::Bool)), | 583 | BinaryOp::LogicOp(..) => { |
584 | Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))) | ||
585 | } | ||
565 | _ => Expectation::none(), | 586 | _ => Expectation::none(), |
566 | }; | 587 | }; |
567 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); | 588 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); |
@@ -688,7 +709,9 @@ impl<'a> InferenceContext<'a> { | |||
688 | ); | 709 | ); |
689 | self.infer_expr( | 710 | self.infer_expr( |
690 | *repeat, | 711 | *repeat, |
691 | &Expectation::has_type(Ty::simple(TypeCtor::Int(IntTy::usize()))), | 712 | &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Uint( |
713 | UintTy::Usize, | ||
714 | )))), | ||
692 | ); | 715 | ); |
693 | } | 716 | } |
694 | } | 717 | } |
@@ -696,22 +719,28 @@ impl<'a> InferenceContext<'a> { | |||
696 | Ty::apply_one(TypeCtor::Array, elem_ty) | 719 | Ty::apply_one(TypeCtor::Array, elem_ty) |
697 | } | 720 | } |
698 | Expr::Literal(lit) => match lit { | 721 | Expr::Literal(lit) => match lit { |
699 | Literal::Bool(..) => Ty::simple(TypeCtor::Bool), | 722 | Literal::Bool(..) => Ty::simple(TypeCtor::Scalar(Scalar::Bool)), |
700 | Literal::String(..) => { | 723 | Literal::String(..) => { |
701 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str)) | 724 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str)) |
702 | } | 725 | } |
703 | Literal::ByteString(..) => { | 726 | Literal::ByteString(..) => { |
704 | let byte_type = Ty::simple(TypeCtor::Int(IntTy::u8())); | 727 | let byte_type = Ty::simple(TypeCtor::Scalar(Scalar::Uint(UintTy::U8))); |
705 | let array_type = Ty::apply_one(TypeCtor::Array, byte_type); | 728 | let array_type = Ty::apply_one(TypeCtor::Array, byte_type); |
706 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) | 729 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) |
707 | } | 730 | } |
708 | Literal::Char(..) => Ty::simple(TypeCtor::Char), | 731 | Literal::Char(..) => Ty::simple(TypeCtor::Scalar(Scalar::Char)), |
709 | Literal::Int(_v, ty) => match ty { | 732 | Literal::Int(_v, ty) => match ty { |
710 | Some(int_ty) => Ty::simple(TypeCtor::Int((*int_ty).into())), | 733 | Some(int_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Int((*int_ty).into()))), |
734 | None => self.table.new_integer_var(), | ||
735 | }, | ||
736 | Literal::Uint(_v, ty) => match ty { | ||
737 | Some(int_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Uint((*int_ty).into()))), | ||
711 | None => self.table.new_integer_var(), | 738 | None => self.table.new_integer_var(), |
712 | }, | 739 | }, |
713 | Literal::Float(_v, ty) => match ty { | 740 | Literal::Float(_v, ty) => match ty { |
714 | Some(float_ty) => Ty::simple(TypeCtor::Float((*float_ty).into())), | 741 | Some(float_ty) => { |
742 | Ty::simple(TypeCtor::Scalar(Scalar::Float((*float_ty).into()))) | ||
743 | } | ||
715 | None => self.table.new_float_var(), | 744 | None => self.table.new_float_var(), |
716 | }, | 745 | }, |
717 | }, | 746 | }, |
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 76984242e..57eb8cede 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -8,8 +8,8 @@ use test_utils::mark; | |||
8 | 8 | ||
9 | use super::{InferenceContext, Obligation}; | 9 | use super::{InferenceContext, Obligation}; |
10 | use crate::{ | 10 | use crate::{ |
11 | BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferTy, Substs, Ty, | 11 | BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferTy, Scalar, Substs, |
12 | TyKind, TypeCtor, TypeWalk, | 12 | Ty, TyKind, TypeCtor, TypeWalk, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | impl<'a> InferenceContext<'a> { | 15 | impl<'a> InferenceContext<'a> { |
@@ -300,10 +300,24 @@ impl InferenceTable { | |||
300 | | (other, Ty::Infer(InferTy::TypeVar(tv))) | 300 | | (other, Ty::Infer(InferTy::TypeVar(tv))) |
301 | | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other) | 301 | | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other) |
302 | | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv))) | 302 | | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv))) |
303 | | (Ty::Infer(InferTy::IntVar(tv)), other @ ty_app!(TypeCtor::Int(_))) | 303 | | (Ty::Infer(InferTy::IntVar(tv)), other @ ty_app!(TypeCtor::Scalar(Scalar::Int(_)))) |
304 | | (other @ ty_app!(TypeCtor::Int(_)), Ty::Infer(InferTy::IntVar(tv))) | 304 | | (other @ ty_app!(TypeCtor::Scalar(Scalar::Int(_))), Ty::Infer(InferTy::IntVar(tv))) |
305 | | (Ty::Infer(InferTy::FloatVar(tv)), other @ ty_app!(TypeCtor::Float(_))) | 305 | | ( |
306 | | (other @ ty_app!(TypeCtor::Float(_)), Ty::Infer(InferTy::FloatVar(tv))) => { | 306 | Ty::Infer(InferTy::IntVar(tv)), |
307 | other @ ty_app!(TypeCtor::Scalar(Scalar::Uint(_))), | ||
308 | ) | ||
309 | | ( | ||
310 | other @ ty_app!(TypeCtor::Scalar(Scalar::Uint(_))), | ||
311 | Ty::Infer(InferTy::IntVar(tv)), | ||
312 | ) | ||
313 | | ( | ||
314 | Ty::Infer(InferTy::FloatVar(tv)), | ||
315 | other @ ty_app!(TypeCtor::Scalar(Scalar::Float(_))), | ||
316 | ) | ||
317 | | ( | ||
318 | other @ ty_app!(TypeCtor::Scalar(Scalar::Float(_))), | ||
319 | Ty::Infer(InferTy::FloatVar(tv)), | ||
320 | ) => { | ||
307 | // the type var is unknown since we tried to resolve it | 321 | // the type var is unknown since we tried to resolve it |
308 | self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); | 322 | self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); |
309 | true | 323 | true |