From 5183c9f08345c664237ae138e86f96ff46714f15 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 28 Feb 2021 01:20:04 +0100 Subject: Introduce TypeCtor::Scalar --- crates/hir_ty/src/infer/expr.rs | 63 +++++++++++++++++++++++++++++----------- crates/hir_ty/src/infer/unify.rs | 26 +++++++++++++---- 2 files changed, 66 insertions(+), 23 deletions(-) (limited to 'crates/hir_ty/src/infer') 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}; use std::{mem, sync::Arc}; use hir_def::{ - builtin_type::Signedness, expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, path::{GenericArg, GenericArgs}, resolver::resolver_for_expr, @@ -16,10 +15,11 @@ use test_utils::mark; use crate::{ autoderef, method_resolution, op, + primitive::UintTy, traits::{FnTrait, InEnvironment}, utils::{generics, variant_data, Generics}, - ApplicationTy, Binders, CallableDefId, InferTy, IntTy, Mutability, Obligation, OpaqueTyId, - Rawness, Substs, TraitRef, Ty, TypeCtor, + ApplicationTy, Binders, CallableDefId, InferTy, Mutability, Obligation, OpaqueTyId, Rawness, + Scalar, Substs, TraitRef, Ty, TypeCtor, }; use super::{ @@ -120,7 +120,10 @@ impl<'a> InferenceContext<'a> { Expr::Missing => Ty::Unknown, Expr::If { condition, then_branch, else_branch } => { // if let is desugared to match, so this is always simple if - self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); + self.infer_expr( + *condition, + &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))), + ); let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); let mut both_arms_diverge = Diverges::Always; @@ -203,7 +206,10 @@ impl<'a> InferenceContext<'a> { label: label.map(|label| self.body[label].name.clone()), }); // while let is desugared to a match loop, so this is always simple while - self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); + self.infer_expr( + *condition, + &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))), + ); self.infer_expr(*body, &Expectation::has_type(Ty::unit())); let _ctxt = self.breakables.pop().expect("breakable stack broken"); // the body may not run, so it diverging doesn't mean we diverge @@ -321,7 +327,7 @@ impl<'a> InferenceContext<'a> { if let Some(guard_expr) = arm.guard { self.infer_expr( guard_expr, - &Expectation::has_type(Ty::simple(TypeCtor::Bool)), + &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))), ); } @@ -534,10 +540,13 @@ impl<'a> InferenceContext<'a> { match &inner_ty { // Fast path for builtins Ty::Apply(ApplicationTy { - ctor: TypeCtor::Int(IntTy { signedness: Signedness::Signed, .. }), + ctor: TypeCtor::Scalar(Scalar::Int(_)), + .. + }) + | Ty::Apply(ApplicationTy { + ctor: TypeCtor::Scalar(Scalar::Float(_)), .. }) - | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(_), .. }) | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => inner_ty, // Otherwise we resolve via the std::ops::Neg trait @@ -548,8 +557,18 @@ impl<'a> InferenceContext<'a> { UnaryOp::Not => { match &inner_ty { // Fast path for builtins - Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. }) - | Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(_), .. }) + Ty::Apply(ApplicationTy { + ctor: TypeCtor::Scalar(Scalar::Bool), + .. + }) + | Ty::Apply(ApplicationTy { + ctor: TypeCtor::Scalar(Scalar::Int(_)), + .. + }) + | Ty::Apply(ApplicationTy { + ctor: TypeCtor::Scalar(Scalar::Uint(_)), + .. + }) | Ty::Infer(InferTy::IntVar(..)) => inner_ty, // Otherwise we resolve via the std::ops::Not trait _ => self @@ -561,7 +580,9 @@ impl<'a> InferenceContext<'a> { Expr::BinaryOp { lhs, rhs, op } => match op { Some(op) => { let lhs_expectation = match op { - BinaryOp::LogicOp(..) => Expectation::has_type(Ty::simple(TypeCtor::Bool)), + BinaryOp::LogicOp(..) => { + Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))) + } _ => Expectation::none(), }; let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); @@ -688,7 +709,9 @@ impl<'a> InferenceContext<'a> { ); self.infer_expr( *repeat, - &Expectation::has_type(Ty::simple(TypeCtor::Int(IntTy::usize()))), + &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Uint( + UintTy::Usize, + )))), ); } } @@ -696,22 +719,28 @@ impl<'a> InferenceContext<'a> { Ty::apply_one(TypeCtor::Array, elem_ty) } Expr::Literal(lit) => match lit { - Literal::Bool(..) => Ty::simple(TypeCtor::Bool), + Literal::Bool(..) => Ty::simple(TypeCtor::Scalar(Scalar::Bool)), Literal::String(..) => { Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str)) } Literal::ByteString(..) => { - let byte_type = Ty::simple(TypeCtor::Int(IntTy::u8())); + let byte_type = Ty::simple(TypeCtor::Scalar(Scalar::Uint(UintTy::U8))); let array_type = Ty::apply_one(TypeCtor::Array, byte_type); Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) } - Literal::Char(..) => Ty::simple(TypeCtor::Char), + Literal::Char(..) => Ty::simple(TypeCtor::Scalar(Scalar::Char)), Literal::Int(_v, ty) => match ty { - Some(int_ty) => Ty::simple(TypeCtor::Int((*int_ty).into())), + Some(int_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Int((*int_ty).into()))), + None => self.table.new_integer_var(), + }, + Literal::Uint(_v, ty) => match ty { + Some(int_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Uint((*int_ty).into()))), None => self.table.new_integer_var(), }, Literal::Float(_v, ty) => match ty { - Some(float_ty) => Ty::simple(TypeCtor::Float((*float_ty).into())), + Some(float_ty) => { + Ty::simple(TypeCtor::Scalar(Scalar::Float((*float_ty).into()))) + } None => self.table.new_float_var(), }, }, 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; use super::{InferenceContext, Obligation}; use crate::{ - BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferTy, Substs, Ty, - TyKind, TypeCtor, TypeWalk, + BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferTy, Scalar, Substs, + Ty, TyKind, TypeCtor, TypeWalk, }; impl<'a> InferenceContext<'a> { @@ -300,10 +300,24 @@ impl InferenceTable { | (other, Ty::Infer(InferTy::TypeVar(tv))) | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other) | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv))) - | (Ty::Infer(InferTy::IntVar(tv)), other @ ty_app!(TypeCtor::Int(_))) - | (other @ ty_app!(TypeCtor::Int(_)), Ty::Infer(InferTy::IntVar(tv))) - | (Ty::Infer(InferTy::FloatVar(tv)), other @ ty_app!(TypeCtor::Float(_))) - | (other @ ty_app!(TypeCtor::Float(_)), Ty::Infer(InferTy::FloatVar(tv))) => { + | (Ty::Infer(InferTy::IntVar(tv)), other @ ty_app!(TypeCtor::Scalar(Scalar::Int(_)))) + | (other @ ty_app!(TypeCtor::Scalar(Scalar::Int(_))), Ty::Infer(InferTy::IntVar(tv))) + | ( + Ty::Infer(InferTy::IntVar(tv)), + other @ ty_app!(TypeCtor::Scalar(Scalar::Uint(_))), + ) + | ( + other @ ty_app!(TypeCtor::Scalar(Scalar::Uint(_))), + Ty::Infer(InferTy::IntVar(tv)), + ) + | ( + Ty::Infer(InferTy::FloatVar(tv)), + other @ ty_app!(TypeCtor::Scalar(Scalar::Float(_))), + ) + | ( + other @ ty_app!(TypeCtor::Scalar(Scalar::Float(_))), + Ty::Infer(InferTy::FloatVar(tv)), + ) => { // the type var is unknown since we tried to resolve it self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); true -- cgit v1.2.3