aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r--crates/hir_ty/src/infer/expr.rs63
-rw-r--r--crates/hir_ty/src/infer/unify.rs26
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};
4use std::{mem, sync::Arc}; 4use std::{mem, sync::Arc};
5 5
6use hir_def::{ 6use 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
17use crate::{ 16use 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
25use super::{ 25use 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
9use super::{InferenceContext, Obligation}; 9use super::{InferenceContext, Obligation};
10use crate::{ 10use 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
15impl<'a> InferenceContext<'a> { 15impl<'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