aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer/expr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/infer/expr.rs')
-rw-r--r--crates/hir_ty/src/infer/expr.rs67
1 files changed, 50 insertions, 17 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index cb59a6937..3fec0e431 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::{self, 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,32 @@ 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(
734 primitive::int_ty_from_builtin(*int_ty),
735 ))),
736 None => self.table.new_integer_var(),
737 },
738 Literal::Uint(_v, ty) => match ty {
739 Some(int_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Uint(
740 primitive::uint_ty_from_builtin(*int_ty),
741 ))),
711 None => self.table.new_integer_var(), 742 None => self.table.new_integer_var(),
712 }, 743 },
713 Literal::Float(_v, ty) => match ty { 744 Literal::Float(_v, ty) => match ty {
714 Some(float_ty) => Ty::simple(TypeCtor::Float((*float_ty).into())), 745 Some(float_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Float(
746 primitive::float_ty_from_builtin(*float_ty),
747 ))),
715 None => self.table.new_float_var(), 748 None => self.table.new_float_var(),
716 }, 749 },
717 }, 750 },