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/display.rs | 12 ++- crates/hir_ty/src/infer.rs | 6 +- crates/hir_ty/src/infer/expr.rs | 63 ++++++++---- crates/hir_ty/src/infer/unify.rs | 26 +++-- crates/hir_ty/src/lib.rs | 51 +++++----- crates/hir_ty/src/method_resolution.rs | 90 +++++------------ crates/hir_ty/src/op.rs | 24 ++--- crates/hir_ty/src/primitive.rs | 157 ++++++++++++++---------------- crates/hir_ty/src/traits/chalk/mapping.rs | 140 ++++++++++++-------------- 9 files changed, 271 insertions(+), 298 deletions(-) (limited to 'crates/hir_ty') diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index 271fcbfaf..cfe9cedb0 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs @@ -4,7 +4,8 @@ use std::{borrow::Cow, fmt}; use crate::{ db::HirDatabase, utils::generics, ApplicationTy, CallableDefId, FnSig, GenericPredicate, - Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, + Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, TraitRef, Ty, + TypeCtor, }; use arrayvec::ArrayVec; use hir_def::{ @@ -241,10 +242,11 @@ impl HirDisplay for ApplicationTy { } match self.ctor { - TypeCtor::Bool => write!(f, "bool")?, - TypeCtor::Char => write!(f, "char")?, - TypeCtor::Int(t) => write!(f, "{}", t)?, - TypeCtor::Float(t) => write!(f, "{}", t)?, + TypeCtor::Scalar(Scalar::Bool) => write!(f, "bool")?, + TypeCtor::Scalar(Scalar::Char) => write!(f, "char")?, + TypeCtor::Scalar(Scalar::Float(t)) => write!(f, "{}", t)?, + TypeCtor::Scalar(Scalar::Int(t)) => write!(f, "{}", t)?, + TypeCtor::Scalar(Scalar::Uint(t)) => write!(f, "{}", t)?, TypeCtor::Str => write!(f, "str")?, TypeCtor::Slice => { let t = self.parameters.as_single(); diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index 4b683c5a7..657f011d2 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs @@ -41,7 +41,7 @@ use super::{ InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, }; use crate::{ - db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, + db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, Scalar, }; pub(crate) use unify::unify; @@ -684,8 +684,8 @@ impl InferTy { fn fallback_value(self) -> Ty { match self { InferTy::TypeVar(..) => Ty::Unknown, - InferTy::IntVar(..) => Ty::simple(TypeCtor::Int(IntTy::i32())), - InferTy::FloatVar(..) => Ty::simple(TypeCtor::Float(FloatTy::f64())), + InferTy::IntVar(..) => Ty::simple(TypeCtor::Scalar(Scalar::Int(IntTy::I32))), + InferTy::FloatVar(..) => Ty::simple(TypeCtor::Scalar(Scalar::Float(FloatTy::F64))), InferTy::MaybeNeverTypeVar(..) => Ty::simple(TypeCtor::Never), } } 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 diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 50d248674..2a45479a8 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs @@ -38,7 +38,7 @@ use itertools::Itertools; use crate::{ db::HirDatabase, display::HirDisplay, - primitive::{FloatTy, IntTy}, + primitive::{FloatTy, IntTy, UintTy}, utils::{generics, make_mut_slice, Generics}, }; @@ -58,23 +58,24 @@ pub enum Lifetime { Static, } +/// Types of scalar values. +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[allow(missing_docs)] +pub enum Scalar { + Bool, + Char, + Int(IntTy), + Uint(UintTy), + Float(FloatTy), +} + /// A type constructor or type name: this might be something like the primitive /// type `bool`, a struct like `Vec`, or things like function pointers or /// tuples. #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] pub enum TypeCtor { - /// The primitive boolean type. Written as `bool`. - Bool, - - /// The primitive character type; holds a Unicode scalar value - /// (a non-surrogate code point). Written as `char`. - Char, - - /// A primitive integer type. For example, `i32`. - Int(IntTy), - - /// A primitive floating-point type. For example, `f64`. - Float(FloatTy), + /// a scalar type like `bool` or `u32` + Scalar(Scalar), /// Structures, enumerations and unions. Adt(AdtId), @@ -152,10 +153,7 @@ pub enum TypeCtor { impl TypeCtor { pub fn num_ty_params(self, db: &dyn HirDatabase) -> usize { match self { - TypeCtor::Bool - | TypeCtor::Char - | TypeCtor::Int(_) - | TypeCtor::Float(_) + TypeCtor::Scalar(_) | TypeCtor::Str | TypeCtor::Never => 0, TypeCtor::Slice @@ -197,10 +195,7 @@ impl TypeCtor { pub fn krate(self, db: &dyn HirDatabase) -> Option { match self { - TypeCtor::Bool - | TypeCtor::Char - | TypeCtor::Int(_) - | TypeCtor::Float(_) + TypeCtor::Scalar(_) | TypeCtor::Str | TypeCtor::Never | TypeCtor::Slice @@ -232,10 +227,7 @@ impl TypeCtor { pub fn as_generic_def(self) -> Option { match self { - TypeCtor::Bool - | TypeCtor::Char - | TypeCtor::Int(_) - | TypeCtor::Float(_) + TypeCtor::Scalar(_) | TypeCtor::Str | TypeCtor::Never | TypeCtor::Slice @@ -741,11 +733,12 @@ impl Ty { } pub fn builtin(builtin: BuiltinType) -> Self { Ty::simple(match builtin { - BuiltinType::Char => TypeCtor::Char, - BuiltinType::Bool => TypeCtor::Bool, + BuiltinType::Char => TypeCtor::Scalar(Scalar::Char), + BuiltinType::Bool => TypeCtor::Scalar(Scalar::Bool), BuiltinType::Str => TypeCtor::Str, - BuiltinType::Int(t) => TypeCtor::Int(IntTy::from(t).into()), - BuiltinType::Float(t) => TypeCtor::Float(FloatTy::from(t).into()), + BuiltinType::Int(t) => TypeCtor::Scalar(Scalar::Int(t.into())), + BuiltinType::Uint(t) => TypeCtor::Scalar(Scalar::Uint(t.into())), + BuiltinType::Float(t) => TypeCtor::Scalar(Scalar::Float(t.into())), }) } diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index b3d1fe9a4..3c817701d 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs @@ -7,11 +7,8 @@ use std::{iter, sync::Arc}; use arrayvec::ArrayVec; use base_db::CrateId; use hir_def::{ - builtin_type::{IntBitness, Signedness}, - lang_item::LangItemTarget, - type_ref::Mutability, - AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule, ImplId, Lookup, ModuleId, - TraitId, + lang_item::LangItemTarget, type_ref::Mutability, AssocContainerId, AssocItemId, FunctionId, + GenericDefId, HasModule, ImplId, Lookup, ModuleId, TraitId, }; use hir_expand::name::Name; use rustc_hash::{FxHashMap, FxHashSet}; @@ -19,10 +16,10 @@ use rustc_hash::{FxHashMap, FxHashSet}; use crate::{ autoderef, db::HirDatabase, - primitive::{FloatBitness, FloatTy, IntTy}, + primitive::{FloatTy, IntTy, UintTy}, utils::all_super_traits, - ApplicationTy, Canonical, DebruijnIndex, InEnvironment, Substs, TraitEnvironment, TraitRef, Ty, - TyKind, TypeCtor, TypeWalk, + ApplicationTy, Canonical, DebruijnIndex, InEnvironment, Scalar, Substs, TraitEnvironment, + TraitRef, Ty, TyKind, TypeCtor, TypeWalk, }; /// This is used as a key for indexing impls. @@ -46,59 +43,23 @@ impl TyFingerprint { } pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ - TyFingerprint::Apply(TypeCtor::Int(IntTy { - signedness: Signedness::Unsigned, - bitness: IntBitness::X8, - })), - TyFingerprint::Apply(TypeCtor::Int(IntTy { - signedness: Signedness::Unsigned, - bitness: IntBitness::X16, - })), - TyFingerprint::Apply(TypeCtor::Int(IntTy { - signedness: Signedness::Unsigned, - bitness: IntBitness::X32, - })), - TyFingerprint::Apply(TypeCtor::Int(IntTy { - signedness: Signedness::Unsigned, - bitness: IntBitness::X64, - })), - TyFingerprint::Apply(TypeCtor::Int(IntTy { - signedness: Signedness::Unsigned, - bitness: IntBitness::X128, - })), - TyFingerprint::Apply(TypeCtor::Int(IntTy { - signedness: Signedness::Unsigned, - bitness: IntBitness::Xsize, - })), - TyFingerprint::Apply(TypeCtor::Int(IntTy { - signedness: Signedness::Signed, - bitness: IntBitness::X8, - })), - TyFingerprint::Apply(TypeCtor::Int(IntTy { - signedness: Signedness::Signed, - bitness: IntBitness::X16, - })), - TyFingerprint::Apply(TypeCtor::Int(IntTy { - signedness: Signedness::Signed, - bitness: IntBitness::X32, - })), - TyFingerprint::Apply(TypeCtor::Int(IntTy { - signedness: Signedness::Signed, - bitness: IntBitness::X64, - })), - TyFingerprint::Apply(TypeCtor::Int(IntTy { - signedness: Signedness::Signed, - bitness: IntBitness::X128, - })), - TyFingerprint::Apply(TypeCtor::Int(IntTy { - signedness: Signedness::Signed, - bitness: IntBitness::Xsize, - })), + TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I8))), + TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I16))), + TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I32))), + TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I64))), + TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I128))), + TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::Isize))), + TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U8))), + TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U16))), + TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U32))), + TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U64))), + TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U128))), + TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::Usize))), ]; pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [ - TyFingerprint::Apply(TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 })), - TyFingerprint::Apply(TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 })), + TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Float(FloatTy::F32))), + TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Float(FloatTy::F64))), ]; /// Trait impls defined or available in some crate. @@ -257,14 +218,15 @@ impl Ty { TypeCtor::ForeignType(type_alias_id) => { return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast())); } - TypeCtor::Bool => lang_item_crate!("bool"), - TypeCtor::Char => lang_item_crate!("char"), - TypeCtor::Float(f) => match f.bitness { + TypeCtor::Scalar(Scalar::Bool) => lang_item_crate!("bool"), + TypeCtor::Scalar(Scalar::Char) => lang_item_crate!("char"), + TypeCtor::Scalar(Scalar::Float(f)) => match f { // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) - FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"), - FloatBitness::X64 => lang_item_crate!("f64", "f64_runtime"), + FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), + FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), }, - TypeCtor::Int(i) => lang_item_crate!(i.ty_to_string()), + TypeCtor::Scalar(Scalar::Int(t)) => lang_item_crate!(t.ty_to_string()), + TypeCtor::Scalar(Scalar::Uint(t)) => lang_item_crate!(t.ty_to_string()), TypeCtor::Str => lang_item_crate!("str_alloc", "str"), TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"), TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"), diff --git a/crates/hir_ty/src/op.rs b/crates/hir_ty/src/op.rs index 0870874fc..a4999c51d 100644 --- a/crates/hir_ty/src/op.rs +++ b/crates/hir_ty/src/op.rs @@ -2,15 +2,17 @@ use hir_def::expr::{ArithOp, BinaryOp, CmpOp}; use super::{InferTy, Ty, TypeCtor}; -use crate::ApplicationTy; +use crate::{ApplicationTy, Scalar}; pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { match op { - BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::simple(TypeCtor::Bool), + BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::simple(TypeCtor::Scalar(Scalar::Bool)), BinaryOp::Assignment { .. } => Ty::unit(), BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => match lhs_ty { Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { - TypeCtor::Int(..) | TypeCtor::Float(..) => lhs_ty, + TypeCtor::Scalar(Scalar::Int(_)) + | TypeCtor::Scalar(Scalar::Uint(_)) + | TypeCtor::Scalar(Scalar::Float(_)) => lhs_ty, _ => Ty::Unknown, }, Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, @@ -18,7 +20,9 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { }, BinaryOp::ArithOp(_) => match rhs_ty { Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { - TypeCtor::Int(..) | TypeCtor::Float(..) => rhs_ty, + TypeCtor::Scalar(Scalar::Int(_)) + | TypeCtor::Scalar(Scalar::Uint(_)) + | TypeCtor::Scalar(Scalar::Float(_)) => rhs_ty, _ => Ty::Unknown, }, Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => rhs_ty, @@ -29,15 +33,11 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { match op { - BinaryOp::LogicOp(..) => Ty::simple(TypeCtor::Bool), + BinaryOp::LogicOp(..) => Ty::simple(TypeCtor::Scalar(Scalar::Bool)), BinaryOp::Assignment { op: None } => lhs_ty, BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty { Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { - TypeCtor::Int(..) - | TypeCtor::Float(..) - | TypeCtor::Str - | TypeCtor::Char - | TypeCtor::Bool => lhs_ty, + TypeCtor::Scalar(_) | TypeCtor::Str => lhs_ty, _ => Ty::Unknown, }, Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, @@ -48,7 +48,9 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { | BinaryOp::Assignment { op: Some(_) } | BinaryOp::ArithOp(_) => match lhs_ty { Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { - TypeCtor::Int(..) | TypeCtor::Float(..) => lhs_ty, + TypeCtor::Scalar(Scalar::Int(_)) + | TypeCtor::Scalar(Scalar::Uint(_)) + | TypeCtor::Scalar(Scalar::Float(_)) => lhs_ty, _ => Ty::Unknown, }, Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, diff --git a/crates/hir_ty/src/primitive.rs b/crates/hir_ty/src/primitive.rs index 37966b709..e727c9581 100644 --- a/crates/hir_ty/src/primitive.rs +++ b/crates/hir_ty/src/primitive.rs @@ -5,18 +5,28 @@ use std::fmt; -pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, FloatBitness, IntBitness, Signedness}; - -#[derive(Copy, Clone, Eq, PartialEq, Hash)] -pub struct IntTy { - pub signedness: Signedness, - pub bitness: IntBitness, +pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint}; + +/// Different signed int types. +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum IntTy { + Isize, + I8, + I16, + I32, + I64, + I128, } -impl fmt::Debug for IntTy { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(self, f) - } +/// Different unsigned int types. +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum UintTy { + Usize, + U8, + U16, + U32, + U64, + U128, } impl fmt::Display for IntTy { @@ -26,75 +36,41 @@ impl fmt::Display for IntTy { } impl IntTy { - pub fn isize() -> IntTy { - IntTy { signedness: Signedness::Signed, bitness: IntBitness::Xsize } - } - - pub fn i8() -> IntTy { - IntTy { signedness: Signedness::Signed, bitness: IntBitness::X8 } - } - - pub fn i16() -> IntTy { - IntTy { signedness: Signedness::Signed, bitness: IntBitness::X16 } - } - - pub fn i32() -> IntTy { - IntTy { signedness: Signedness::Signed, bitness: IntBitness::X32 } - } - - pub fn i64() -> IntTy { - IntTy { signedness: Signedness::Signed, bitness: IntBitness::X64 } - } - - pub fn i128() -> IntTy { - IntTy { signedness: Signedness::Signed, bitness: IntBitness::X128 } - } - - pub fn usize() -> IntTy { - IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::Xsize } - } - - pub fn u8() -> IntTy { - IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X8 } - } - - pub fn u16() -> IntTy { - IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X16 } - } - - pub fn u32() -> IntTy { - IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X32 } - } - - pub fn u64() -> IntTy { - IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X64 } + pub fn ty_to_string(self) -> &'static str { + match self { + IntTy::Isize => "isize", + IntTy::I8 => "i8", + IntTy::I16 => "i16", + IntTy::I32 => "i32", + IntTy::I64 => "i64", + IntTy::I128 => "i128", + } } +} - pub fn u128() -> IntTy { - IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X128 } +impl fmt::Display for UintTy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.ty_to_string()) } +} +impl UintTy { pub fn ty_to_string(self) -> &'static str { - match (self.signedness, self.bitness) { - (Signedness::Signed, IntBitness::Xsize) => "isize", - (Signedness::Signed, IntBitness::X8) => "i8", - (Signedness::Signed, IntBitness::X16) => "i16", - (Signedness::Signed, IntBitness::X32) => "i32", - (Signedness::Signed, IntBitness::X64) => "i64", - (Signedness::Signed, IntBitness::X128) => "i128", - (Signedness::Unsigned, IntBitness::Xsize) => "usize", - (Signedness::Unsigned, IntBitness::X8) => "u8", - (Signedness::Unsigned, IntBitness::X16) => "u16", - (Signedness::Unsigned, IntBitness::X32) => "u32", - (Signedness::Unsigned, IntBitness::X64) => "u64", - (Signedness::Unsigned, IntBitness::X128) => "u128", + match self { + UintTy::Usize => "usize", + UintTy::U8 => "u8", + UintTy::U16 => "u16", + UintTy::U32 => "u32", + UintTy::U64 => "u64", + UintTy::U128 => "u128", } } } -#[derive(Copy, Clone, PartialEq, Eq, Hash)] -pub struct FloatTy { - pub bitness: FloatBitness, +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum FloatTy { + F32, + F64, } impl fmt::Debug for FloatTy { @@ -110,30 +86,45 @@ impl fmt::Display for FloatTy { } impl FloatTy { - pub fn f32() -> FloatTy { - FloatTy { bitness: FloatBitness::X32 } - } - - pub fn f64() -> FloatTy { - FloatTy { bitness: FloatBitness::X64 } - } - pub fn ty_to_string(self) -> &'static str { - match self.bitness { - FloatBitness::X32 => "f32", - FloatBitness::X64 => "f64", + match self { + FloatTy::F32 => "f32", + FloatTy::F64 => "f64", } } } impl From for IntTy { fn from(t: BuiltinInt) -> Self { - IntTy { signedness: t.signedness, bitness: t.bitness } + match t { + BuiltinInt::Isize => Self::Isize, + BuiltinInt::I8 => Self::I8, + BuiltinInt::I16 => Self::I16, + BuiltinInt::I32 => Self::I32, + BuiltinInt::I64 => Self::I64, + BuiltinInt::I128 => Self::I128, + } + } +} + +impl From for UintTy { + fn from(t: BuiltinUint) -> Self { + match t { + BuiltinUint::Usize => Self::Usize, + BuiltinUint::U8 => Self::U8, + BuiltinUint::U16 => Self::U16, + BuiltinUint::U32 => Self::U32, + BuiltinUint::U64 => Self::U64, + BuiltinUint::U128 => Self::U128, + } } } impl From for FloatTy { fn from(t: BuiltinFloat) -> Self { - FloatTy { bitness: t.bitness } + match t { + BuiltinFloat::F32 => Self::F32, + BuiltinFloat::F64 => Self::F64, + } } } diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 8700d664e..0e9fc3265 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs @@ -4,7 +4,7 @@ //! conversions. use chalk_ir::{ - cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData, PlaceholderIndex, Scalar, + cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData, PlaceholderIndex, UniverseIndex, }; use chalk_solve::rust_ir; @@ -14,10 +14,11 @@ use hir_def::{type_ref::Mutability, AssocContainerId, GenericDefId, Lookup, Type use crate::{ db::HirDatabase, - primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness}, + primitive::{FloatTy, IntTy, UintTy}, traits::{Canonical, Obligation}, ApplicationTy, CallableDefId, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId, - ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeCtor, + ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, TraitRef, Ty, TyKind, + TypeCtor, }; use super::interner::*; @@ -63,19 +64,31 @@ impl ToChalk for Ty { chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner) } - TypeCtor::Bool => chalk_ir::TyKind::Scalar(Scalar::Bool).intern(&Interner), - TypeCtor::Char => chalk_ir::TyKind::Scalar(Scalar::Char).intern(&Interner), - TypeCtor::Int(int_ty) => { - chalk_ir::TyKind::Scalar(int_ty_to_chalk(int_ty)).intern(&Interner) - } - TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }) => { - chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) - .intern(&Interner) - } - TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }) => { - chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) - .intern(&Interner) - } + TypeCtor::Scalar(scalar) => chalk_ir::TyKind::Scalar(match scalar { + Scalar::Bool => chalk_ir::Scalar::Bool, + Scalar::Char => chalk_ir::Scalar::Char, + Scalar::Int(it) => chalk_ir::Scalar::Int(match it { + IntTy::Isize => chalk_ir::IntTy::Isize, + IntTy::I8 => chalk_ir::IntTy::I8, + IntTy::I16 => chalk_ir::IntTy::I16, + IntTy::I32 => chalk_ir::IntTy::I32, + IntTy::I64 => chalk_ir::IntTy::I64, + IntTy::I128 => chalk_ir::IntTy::I128, + }), + Scalar::Uint(it) => chalk_ir::Scalar::Uint(match it { + UintTy::Usize => chalk_ir::UintTy::Usize, + UintTy::U8 => chalk_ir::UintTy::U8, + UintTy::U16 => chalk_ir::UintTy::U16, + UintTy::U32 => chalk_ir::UintTy::U32, + UintTy::U64 => chalk_ir::UintTy::U64, + UintTy::U128 => chalk_ir::UintTy::U128, + }), + Scalar::Float(it) => chalk_ir::Scalar::Float(match it { + FloatTy::F32 => chalk_ir::FloatTy::F32, + FloatTy::F64 => chalk_ir::FloatTy::F64, + }), + }) + .intern(&Interner), TypeCtor::Tuple { cardinality } => { let substitution = apply_ty.parameters.to_chalk(db); @@ -219,21 +232,37 @@ impl ToChalk for Ty { apply_ty_from_chalk(db, TypeCtor::OpaqueType(from_chalk(db, opaque_type_id)), subst) } - chalk_ir::TyKind::Scalar(Scalar::Bool) => Ty::simple(TypeCtor::Bool), - chalk_ir::TyKind::Scalar(Scalar::Char) => Ty::simple(TypeCtor::Char), - chalk_ir::TyKind::Scalar(Scalar::Int(int_ty)) => Ty::simple(TypeCtor::Int(IntTy { - signedness: Signedness::Signed, - bitness: bitness_from_chalk_int(int_ty), - })), - chalk_ir::TyKind::Scalar(Scalar::Uint(uint_ty)) => Ty::simple(TypeCtor::Int(IntTy { - signedness: Signedness::Unsigned, - bitness: bitness_from_chalk_uint(uint_ty), - })), - chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => { - Ty::simple(TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 })) + chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Bool) => { + Ty::simple(TypeCtor::Scalar(Scalar::Bool)) + } + chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Char) => { + Ty::simple(TypeCtor::Scalar(Scalar::Char)) + } + chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Int(int_ty)) => { + Ty::simple(TypeCtor::Scalar(Scalar::Int(match int_ty { + chalk_ir::IntTy::Isize => IntTy::Isize, + chalk_ir::IntTy::I8 => IntTy::I8, + chalk_ir::IntTy::I16 => IntTy::I16, + chalk_ir::IntTy::I32 => IntTy::I32, + chalk_ir::IntTy::I64 => IntTy::I64, + chalk_ir::IntTy::I128 => IntTy::I128, + }))) } - chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => { - Ty::simple(TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 })) + chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(int_ty)) => { + Ty::simple(TypeCtor::Scalar(Scalar::Uint(match int_ty { + chalk_ir::UintTy::Usize => UintTy::Usize, + chalk_ir::UintTy::U8 => UintTy::U8, + chalk_ir::UintTy::U16 => UintTy::U16, + chalk_ir::UintTy::U32 => UintTy::U32, + chalk_ir::UintTy::U64 => UintTy::U64, + chalk_ir::UintTy::U128 => UintTy::U128, + }))) + } + chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Float(float_ty)) => { + Ty::simple(TypeCtor::Scalar(Scalar::Float(match float_ty { + chalk_ir::FloatTy::F32 => FloatTy::F32, + chalk_ir::FloatTy::F64 => FloatTy::F64, + }))) } chalk_ir::TyKind::Tuple(cardinality, subst) => { apply_ty_from_chalk(db, TypeCtor::Tuple { cardinality: cardinality as u16 }, subst) @@ -293,7 +322,7 @@ fn ref_to_chalk( fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty { let arg = subst[0].clone().to_chalk(db); let usize_ty = - chalk_ir::TyKind::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)).intern(&Interner); + chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::Usize)).intern(&Interner); let const_ = chalk_ir::ConstData { ty: usize_ty, value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }), @@ -364,55 +393,6 @@ impl ToChalk for OpaqueTyId { } } -fn bitness_from_chalk_uint(uint_ty: chalk_ir::UintTy) -> IntBitness { - use chalk_ir::UintTy; - - match uint_ty { - UintTy::Usize => IntBitness::Xsize, - UintTy::U8 => IntBitness::X8, - UintTy::U16 => IntBitness::X16, - UintTy::U32 => IntBitness::X32, - UintTy::U64 => IntBitness::X64, - UintTy::U128 => IntBitness::X128, - } -} - -fn bitness_from_chalk_int(int_ty: chalk_ir::IntTy) -> IntBitness { - use chalk_ir::IntTy; - - match int_ty { - IntTy::Isize => IntBitness::Xsize, - IntTy::I8 => IntBitness::X8, - IntTy::I16 => IntBitness::X16, - IntTy::I32 => IntBitness::X32, - IntTy::I64 => IntBitness::X64, - IntTy::I128 => IntBitness::X128, - } -} - -fn int_ty_to_chalk(int_ty: IntTy) -> Scalar { - use chalk_ir::{IntTy, UintTy}; - - match int_ty.signedness { - Signedness::Signed => Scalar::Int(match int_ty.bitness { - IntBitness::Xsize => IntTy::Isize, - IntBitness::X8 => IntTy::I8, - IntBitness::X16 => IntTy::I16, - IntBitness::X32 => IntTy::I32, - IntBitness::X64 => IntTy::I64, - IntBitness::X128 => IntTy::I128, - }), - Signedness::Unsigned => Scalar::Uint(match int_ty.bitness { - IntBitness::Xsize => UintTy::Usize, - IntBitness::X8 => UintTy::U8, - IntBitness::X16 => UintTy::U16, - IntBitness::X32 => UintTy::U32, - IntBitness::X64 => UintTy::U64, - IntBitness::X128 => UintTy::U128, - }), - } -} - impl ToChalk for Mutability { type Chalk = chalk_ir::Mutability; fn to_chalk(self, _db: &dyn HirDatabase) -> Self::Chalk { -- cgit v1.2.3