7804: Introduce TypeCtor::Scalar r=lnicola a=Veykril

`TypeCtor::Int(..) | TypeCtor::Float(..) | TypeCtor::Char | TypeCtor::Bool` => `TypeCtor::Scalar(..)`, in this case we can actually just straight up use `chalk_ir::Scalar` already since its just a POD without any IDs or anything.

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
bors[bot] 2021-02-28 13:36:44 +00:00 committed by GitHub
commit 803ff2e55e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 269 additions and 418 deletions

View file

@ -32,8 +32,8 @@ use hir_ty::{
method_resolution, method_resolution,
traits::{FnTrait, Solution, SolutionVariables}, traits::{FnTrait, Solution, SolutionVariables},
ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate, ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate,
InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, Ty, InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment,
TyDefId, TyKind, TypeCtor, Ty, TyDefId, TyKind, TypeCtor,
}; };
use rustc_hash::FxHashSet; use rustc_hash::FxHashSet;
use stdx::{format_to, impl_from}; use stdx::{format_to, impl_from};
@ -1553,7 +1553,10 @@ impl Type {
) )
} }
pub fn is_bool(&self) -> bool { pub fn is_bool(&self) -> bool {
matches!(self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. })) matches!(
self.ty.value,
Ty::Apply(ApplicationTy { ctor: TypeCtor::Scalar(Scalar::Bool), .. })
)
} }
pub fn is_mutable_reference(&self) -> bool { pub fn is_mutable_reference(&self) -> bool {

View file

@ -24,7 +24,7 @@ use test_utils::mark;
use crate::{ use crate::{
adt::StructKind, adt::StructKind,
body::{Body, BodySourceMap, Expander, LabelSource, PatPtr, SyntheticSyntax}, body::{Body, BodySourceMap, Expander, LabelSource, PatPtr, SyntheticSyntax},
builtin_type::{BuiltinFloat, BuiltinInt}, builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint},
db::DefDatabase, db::DefDatabase,
diagnostics::{InactiveCode, MacroError, UnresolvedProcMacro}, diagnostics::{InactiveCode, MacroError, UnresolvedProcMacro},
expr::{ expr::{
@ -1065,11 +1065,16 @@ impl From<ast::LiteralKind> for Literal {
fn from(ast_lit_kind: ast::LiteralKind) -> Self { fn from(ast_lit_kind: ast::LiteralKind) -> Self {
match ast_lit_kind { match ast_lit_kind {
LiteralKind::IntNumber(lit) => { LiteralKind::IntNumber(lit) => {
if let Some(float_suffix) = lit.suffix().and_then(BuiltinFloat::from_suffix) { if let builtin @ Some(_) = lit.suffix().and_then(BuiltinFloat::from_suffix) {
return Literal::Float(Default::default(), Some(float_suffix)); return Literal::Float(Default::default(), builtin);
} else if let builtin @ Some(_) =
lit.suffix().and_then(|it| BuiltinInt::from_suffix(&it))
{
Literal::Int(Default::default(), builtin)
} else {
let builtin = lit.suffix().and_then(|it| BuiltinUint::from_suffix(&it));
Literal::Uint(Default::default(), builtin)
} }
let ty = lit.suffix().and_then(|it| BuiltinInt::from_suffix(&it));
Literal::Int(Default::default(), ty)
} }
LiteralKind::FloatNumber(lit) => { LiteralKind::FloatNumber(lit) => {
let ty = lit.suffix().and_then(|it| BuiltinFloat::from_suffix(&it)); let ty = lit.suffix().and_then(|it| BuiltinFloat::from_suffix(&it));
@ -1077,7 +1082,7 @@ impl From<ast::LiteralKind> for Literal {
} }
LiteralKind::ByteString(_) => Literal::ByteString(Default::default()), LiteralKind::ByteString(_) => Literal::ByteString(Default::default()),
LiteralKind::String(_) => Literal::String(Default::default()), LiteralKind::String(_) => Literal::String(Default::default()),
LiteralKind::Byte => Literal::Int(Default::default(), Some(BuiltinInt::U8)), LiteralKind::Byte => Literal::Uint(Default::default(), Some(BuiltinUint::U8)),
LiteralKind::Bool(val) => Literal::Bool(val), LiteralKind::Bool(val) => Literal::Bool(val),
LiteralKind::Char => Literal::Char(Default::default()), LiteralKind::Char => Literal::Char(Default::default()),
} }

View file

@ -6,38 +6,32 @@
use std::fmt; use std::fmt;
use hir_expand::name::{name, AsName, Name}; use hir_expand::name::{name, AsName, Name};
/// Different signed int types.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Signedness { pub enum BuiltinInt {
Signed, Isize,
Unsigned, I8,
I16,
I32,
I64,
I128,
} }
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] /// Different unsigned int types.
pub enum IntBitness { #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
Xsize, pub enum BuiltinUint {
X8, Usize,
X16, U8,
X32, U16,
X64, U32,
X128, U64,
U128,
} }
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum FloatBitness { pub enum BuiltinFloat {
X32, F32,
X64, F64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct BuiltinInt {
pub signedness: Signedness,
pub bitness: IntBitness,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct BuiltinFloat {
pub bitness: FloatBitness,
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -46,6 +40,7 @@ pub enum BuiltinType {
Bool, Bool,
Str, Str,
Int(BuiltinInt), Int(BuiltinInt),
Uint(BuiltinUint),
Float(BuiltinFloat), Float(BuiltinFloat),
} }
@ -56,19 +51,19 @@ impl BuiltinType {
(name![bool], BuiltinType::Bool), (name![bool], BuiltinType::Bool),
(name![str], BuiltinType::Str), (name![str], BuiltinType::Str),
(name![isize], BuiltinType::Int(BuiltinInt::ISIZE)), (name![isize], BuiltinType::Int(BuiltinInt::Isize)),
(name![i8], BuiltinType::Int(BuiltinInt::I8)), (name![i8], BuiltinType::Int(BuiltinInt::I8)),
(name![i16], BuiltinType::Int(BuiltinInt::I16)), (name![i16], BuiltinType::Int(BuiltinInt::I16)),
(name![i32], BuiltinType::Int(BuiltinInt::I32)), (name![i32], BuiltinType::Int(BuiltinInt::I32)),
(name![i64], BuiltinType::Int(BuiltinInt::I64)), (name![i64], BuiltinType::Int(BuiltinInt::I64)),
(name![i128], BuiltinType::Int(BuiltinInt::I128)), (name![i128], BuiltinType::Int(BuiltinInt::I128)),
(name![usize], BuiltinType::Int(BuiltinInt::USIZE)), (name![usize], BuiltinType::Uint(BuiltinUint::Usize)),
(name![u8], BuiltinType::Int(BuiltinInt::U8)), (name![u8], BuiltinType::Uint(BuiltinUint::U8)),
(name![u16], BuiltinType::Int(BuiltinInt::U16)), (name![u16], BuiltinType::Uint(BuiltinUint::U16)),
(name![u32], BuiltinType::Int(BuiltinInt::U32)), (name![u32], BuiltinType::Uint(BuiltinUint::U32)),
(name![u64], BuiltinType::Int(BuiltinInt::U64)), (name![u64], BuiltinType::Uint(BuiltinUint::U64)),
(name![u128], BuiltinType::Int(BuiltinInt::U128)), (name![u128], BuiltinType::Uint(BuiltinUint::U128)),
(name![f32], BuiltinType::Float(BuiltinFloat::F32)), (name![f32], BuiltinType::Float(BuiltinFloat::F32)),
(name![f64], BuiltinType::Float(BuiltinFloat::F64)), (name![f64], BuiltinType::Float(BuiltinFloat::F64)),
@ -81,24 +76,25 @@ impl AsName for BuiltinType {
BuiltinType::Char => name![char], BuiltinType::Char => name![char],
BuiltinType::Bool => name![bool], BuiltinType::Bool => name![bool],
BuiltinType::Str => name![str], BuiltinType::Str => name![str],
BuiltinType::Int(BuiltinInt { signedness, bitness }) => match (signedness, bitness) { BuiltinType::Int(it) => match it {
(Signedness::Signed, IntBitness::Xsize) => name![isize], BuiltinInt::Isize => name![isize],
(Signedness::Signed, IntBitness::X8) => name![i8], BuiltinInt::I8 => name![i8],
(Signedness::Signed, IntBitness::X16) => name![i16], BuiltinInt::I16 => name![i16],
(Signedness::Signed, IntBitness::X32) => name![i32], BuiltinInt::I32 => name![i32],
(Signedness::Signed, IntBitness::X64) => name![i64], BuiltinInt::I64 => name![i64],
(Signedness::Signed, IntBitness::X128) => name![i128], BuiltinInt::I128 => name![i128],
(Signedness::Unsigned, IntBitness::Xsize) => name![usize],
(Signedness::Unsigned, IntBitness::X8) => name![u8],
(Signedness::Unsigned, IntBitness::X16) => name![u16],
(Signedness::Unsigned, IntBitness::X32) => name![u32],
(Signedness::Unsigned, IntBitness::X64) => name![u64],
(Signedness::Unsigned, IntBitness::X128) => name![u128],
}, },
BuiltinType::Float(BuiltinFloat { bitness }) => match bitness { BuiltinType::Uint(it) => match it {
FloatBitness::X32 => name![f32], BuiltinUint::Usize => name![usize],
FloatBitness::X64 => name![f64], BuiltinUint::U8 => name![u8],
BuiltinUint::U16 => name![u16],
BuiltinUint::U32 => name![u32],
BuiltinUint::U64 => name![u64],
BuiltinUint::U128 => name![u128],
},
BuiltinType::Float(it) => match it {
BuiltinFloat::F32 => name![f32],
BuiltinFloat::F64 => name![f64],
}, },
} }
} }
@ -113,31 +109,26 @@ impl fmt::Display for BuiltinType {
#[rustfmt::skip] #[rustfmt::skip]
impl BuiltinInt { impl BuiltinInt {
pub const ISIZE: BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::Xsize };
pub const I8 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X8 };
pub const I16 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X16 };
pub const I32 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X32 };
pub const I64 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X64 };
pub const I128 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X128 };
pub const USIZE: BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::Xsize };
pub const U8 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X8 };
pub const U16 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X16 };
pub const U32 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X32 };
pub const U64 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X64 };
pub const U128 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X128 };
pub fn from_suffix(suffix: &str) -> Option<BuiltinInt> { pub fn from_suffix(suffix: &str) -> Option<BuiltinInt> {
let res = match suffix { let res = match suffix {
"isize" => Self::ISIZE, "isize" => Self::Isize,
"i8" => Self::I8, "i8" => Self::I8,
"i16" => Self::I16, "i16" => Self::I16,
"i32" => Self::I32, "i32" => Self::I32,
"i64" => Self::I64, "i64" => Self::I64,
"i128" => Self::I128, "i128" => Self::I128,
"usize" => Self::USIZE, _ => return None,
};
Some(res)
}
}
#[rustfmt::skip]
impl BuiltinUint {
pub fn from_suffix(suffix: &str) -> Option<BuiltinUint> {
let res = match suffix {
"usize" => Self::Usize,
"u8" => Self::U8, "u8" => Self::U8,
"u16" => Self::U16, "u16" => Self::U16,
"u32" => Self::U32, "u32" => Self::U32,
@ -152,9 +143,6 @@ impl BuiltinInt {
#[rustfmt::skip] #[rustfmt::skip]
impl BuiltinFloat { impl BuiltinFloat {
pub const F32: BuiltinFloat = BuiltinFloat { bitness: FloatBitness::X32 };
pub const F64: BuiltinFloat = BuiltinFloat { bitness: FloatBitness::X64 };
pub fn from_suffix(suffix: &str) -> Option<BuiltinFloat> { pub fn from_suffix(suffix: &str) -> Option<BuiltinFloat> {
let res = match suffix { let res = match suffix {
"f32" => BuiltinFloat::F32, "f32" => BuiltinFloat::F32,

View file

@ -17,7 +17,7 @@ use la_arena::{Idx, RawIdx};
use syntax::ast::RangeOp; use syntax::ast::RangeOp;
use crate::{ use crate::{
builtin_type::{BuiltinFloat, BuiltinInt}, builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint},
path::{GenericArgs, Path}, path::{GenericArgs, Path},
type_ref::{Mutability, Rawness, TypeRef}, type_ref::{Mutability, Rawness, TypeRef},
BlockId, BlockId,
@ -43,6 +43,7 @@ pub enum Literal {
Char(char), Char(char),
Bool(bool), Bool(bool),
Int(u64, Option<BuiltinInt>), Int(u64, Option<BuiltinInt>),
Uint(u64, Option<BuiltinUint>),
Float(u64, Option<BuiltinFloat>), // FIXME: f64 is not Eq Float(u64, Option<BuiltinFloat>), // FIXME: f64 is not Eq
} }

View file

@ -3,8 +3,9 @@
use std::{borrow::Cow, fmt}; use std::{borrow::Cow, fmt};
use crate::{ use crate::{
db::HirDatabase, utils::generics, ApplicationTy, CallableDefId, FnSig, GenericPredicate, db::HirDatabase, primitive, utils::generics, ApplicationTy, CallableDefId, FnSig,
Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, GenericPredicate, Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs,
TraitRef, Ty, TypeCtor,
}; };
use arrayvec::ArrayVec; use arrayvec::ArrayVec;
use hir_def::{ use hir_def::{
@ -241,10 +242,13 @@ impl HirDisplay for ApplicationTy {
} }
match self.ctor { match self.ctor {
TypeCtor::Bool => write!(f, "bool")?, TypeCtor::Scalar(Scalar::Bool) => write!(f, "bool")?,
TypeCtor::Char => write!(f, "char")?, TypeCtor::Scalar(Scalar::Char) => write!(f, "char")?,
TypeCtor::Int(t) => write!(f, "{}", t)?, TypeCtor::Scalar(Scalar::Float(t)) => {
TypeCtor::Float(t) => write!(f, "{}", t)?, write!(f, "{}", primitive::float_ty_to_string(t))?
}
TypeCtor::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?,
TypeCtor::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?,
TypeCtor::Str => write!(f, "str")?, TypeCtor::Str => write!(f, "str")?,
TypeCtor::Slice => { TypeCtor::Slice => {
let t = self.parameters.as_single(); let t = self.parameters.as_single();

View file

@ -41,7 +41,7 @@ use super::{
InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk,
}; };
use crate::{ use crate::{
db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, Scalar,
}; };
pub(crate) use unify::unify; pub(crate) use unify::unify;
@ -684,8 +684,8 @@ impl InferTy {
fn fallback_value(self) -> Ty { fn fallback_value(self) -> Ty {
match self { match self {
InferTy::TypeVar(..) => Ty::Unknown, InferTy::TypeVar(..) => Ty::Unknown,
InferTy::IntVar(..) => Ty::simple(TypeCtor::Int(IntTy::i32())), InferTy::IntVar(..) => Ty::simple(TypeCtor::Scalar(Scalar::Int(IntTy::I32))),
InferTy::FloatVar(..) => Ty::simple(TypeCtor::Float(FloatTy::f64())), InferTy::FloatVar(..) => Ty::simple(TypeCtor::Scalar(Scalar::Float(FloatTy::F64))),
InferTy::MaybeNeverTypeVar(..) => Ty::simple(TypeCtor::Never), InferTy::MaybeNeverTypeVar(..) => Ty::simple(TypeCtor::Never),
} }
} }

View file

@ -4,7 +4,6 @@ use std::iter::{repeat, repeat_with};
use std::{mem, sync::Arc}; use std::{mem, sync::Arc};
use hir_def::{ use hir_def::{
builtin_type::Signedness,
expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
path::{GenericArg, GenericArgs}, path::{GenericArg, GenericArgs},
resolver::resolver_for_expr, resolver::resolver_for_expr,
@ -16,10 +15,11 @@ use test_utils::mark;
use crate::{ use crate::{
autoderef, method_resolution, op, autoderef, method_resolution, op,
primitive::{self, UintTy},
traits::{FnTrait, InEnvironment}, traits::{FnTrait, InEnvironment},
utils::{generics, variant_data, Generics}, utils::{generics, variant_data, Generics},
ApplicationTy, Binders, CallableDefId, InferTy, IntTy, Mutability, Obligation, OpaqueTyId, ApplicationTy, Binders, CallableDefId, InferTy, Mutability, Obligation, OpaqueTyId, Rawness,
Rawness, Substs, TraitRef, Ty, TypeCtor, Scalar, Substs, TraitRef, Ty, TypeCtor,
}; };
use super::{ use super::{
@ -120,7 +120,10 @@ impl<'a> InferenceContext<'a> {
Expr::Missing => Ty::Unknown, Expr::Missing => Ty::Unknown,
Expr::If { condition, then_branch, else_branch } => { Expr::If { condition, then_branch, else_branch } => {
// if let is desugared to match, so this is always simple if // 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 condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
let mut both_arms_diverge = Diverges::Always; let mut both_arms_diverge = Diverges::Always;
@ -203,7 +206,10 @@ impl<'a> InferenceContext<'a> {
label: label.map(|label| self.body[label].name.clone()), label: label.map(|label| self.body[label].name.clone()),
}); });
// while let is desugared to a match loop, so this is always simple while // 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())); self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
let _ctxt = self.breakables.pop().expect("breakable stack broken"); let _ctxt = self.breakables.pop().expect("breakable stack broken");
// the body may not run, so it diverging doesn't mean we diverge // 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 { if let Some(guard_expr) = arm.guard {
self.infer_expr( self.infer_expr(
guard_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 { match &inner_ty {
// Fast path for builtins // Fast path for builtins
Ty::Apply(ApplicationTy { 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::IntVar(..))
| Ty::Infer(InferTy::FloatVar(..)) => inner_ty, | Ty::Infer(InferTy::FloatVar(..)) => inner_ty,
// Otherwise we resolve via the std::ops::Neg trait // Otherwise we resolve via the std::ops::Neg trait
@ -548,8 +557,18 @@ impl<'a> InferenceContext<'a> {
UnaryOp::Not => { UnaryOp::Not => {
match &inner_ty { match &inner_ty {
// Fast path for builtins // Fast path for builtins
Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. }) Ty::Apply(ApplicationTy {
| Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(_), .. }) 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, | Ty::Infer(InferTy::IntVar(..)) => inner_ty,
// Otherwise we resolve via the std::ops::Not trait // Otherwise we resolve via the std::ops::Not trait
_ => self _ => self
@ -561,7 +580,9 @@ impl<'a> InferenceContext<'a> {
Expr::BinaryOp { lhs, rhs, op } => match op { Expr::BinaryOp { lhs, rhs, op } => match op {
Some(op) => { Some(op) => {
let lhs_expectation = match 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(), _ => Expectation::none(),
}; };
let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
@ -688,7 +709,9 @@ impl<'a> InferenceContext<'a> {
); );
self.infer_expr( self.infer_expr(
*repeat, *repeat,
&Expectation::has_type(Ty::simple(TypeCtor::Int(IntTy::usize()))), &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Uint(
UintTy::Usize,
)))),
); );
} }
} }
@ -696,22 +719,32 @@ impl<'a> InferenceContext<'a> {
Ty::apply_one(TypeCtor::Array, elem_ty) Ty::apply_one(TypeCtor::Array, elem_ty)
} }
Expr::Literal(lit) => match lit { Expr::Literal(lit) => match lit {
Literal::Bool(..) => Ty::simple(TypeCtor::Bool), Literal::Bool(..) => Ty::simple(TypeCtor::Scalar(Scalar::Bool)),
Literal::String(..) => { Literal::String(..) => {
Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str)) Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str))
} }
Literal::ByteString(..) => { 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); let array_type = Ty::apply_one(TypeCtor::Array, byte_type);
Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_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 { 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(
primitive::int_ty_from_builtin(*int_ty),
))),
None => self.table.new_integer_var(),
},
Literal::Uint(_v, ty) => match ty {
Some(int_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Uint(
primitive::uint_ty_from_builtin(*int_ty),
))),
None => self.table.new_integer_var(), None => self.table.new_integer_var(),
}, },
Literal::Float(_v, ty) => match ty { 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(
primitive::float_ty_from_builtin(*float_ty),
))),
None => self.table.new_float_var(), None => self.table.new_float_var(),
}, },
}, },

View file

@ -8,8 +8,8 @@ use test_utils::mark;
use super::{InferenceContext, Obligation}; use super::{InferenceContext, Obligation};
use crate::{ use crate::{
BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferTy, Substs, Ty, BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferTy, Scalar, Substs,
TyKind, TypeCtor, TypeWalk, Ty, TyKind, TypeCtor, TypeWalk,
}; };
impl<'a> InferenceContext<'a> { impl<'a> InferenceContext<'a> {
@ -300,10 +300,24 @@ impl InferenceTable {
| (other, Ty::Infer(InferTy::TypeVar(tv))) | (other, Ty::Infer(InferTy::TypeVar(tv)))
| (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other) | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other)
| (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv))) | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv)))
| (Ty::Infer(InferTy::IntVar(tv)), other @ ty_app!(TypeCtor::Int(_))) | (Ty::Infer(InferTy::IntVar(tv)), other @ ty_app!(TypeCtor::Scalar(Scalar::Int(_))))
| (other @ ty_app!(TypeCtor::Int(_)), Ty::Infer(InferTy::IntVar(tv))) | (other @ ty_app!(TypeCtor::Scalar(Scalar::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::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 // the type var is unknown since we tried to resolve it
self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone()));
true true

View file

@ -38,7 +38,6 @@ use itertools::Itertools;
use crate::{ use crate::{
db::HirDatabase, db::HirDatabase,
display::HirDisplay, display::HirDisplay,
primitive::{FloatTy, IntTy},
utils::{generics, make_mut_slice, Generics}, utils::{generics, make_mut_slice, Generics},
}; };
@ -50,7 +49,7 @@ pub use lower::{
}; };
pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment};
pub use chalk_ir::{BoundVar, DebruijnIndex}; pub use chalk_ir::{BoundVar, DebruijnIndex, Scalar};
#[derive(Clone, PartialEq, Eq, Debug, Hash)] #[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub enum Lifetime { pub enum Lifetime {
@ -63,18 +62,8 @@ pub enum Lifetime {
/// tuples. /// tuples.
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub enum TypeCtor { pub enum TypeCtor {
/// The primitive boolean type. Written as `bool`. /// a scalar type like `bool` or `u32`
Bool, Scalar(Scalar),
/// 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),
/// Structures, enumerations and unions. /// Structures, enumerations and unions.
Adt(AdtId), Adt(AdtId),
@ -152,10 +141,7 @@ pub enum TypeCtor {
impl TypeCtor { impl TypeCtor {
pub fn num_ty_params(self, db: &dyn HirDatabase) -> usize { pub fn num_ty_params(self, db: &dyn HirDatabase) -> usize {
match self { match self {
TypeCtor::Bool TypeCtor::Scalar(_)
| TypeCtor::Char
| TypeCtor::Int(_)
| TypeCtor::Float(_)
| TypeCtor::Str | TypeCtor::Str
| TypeCtor::Never => 0, | TypeCtor::Never => 0,
TypeCtor::Slice TypeCtor::Slice
@ -197,10 +183,7 @@ impl TypeCtor {
pub fn krate(self, db: &dyn HirDatabase) -> Option<CrateId> { pub fn krate(self, db: &dyn HirDatabase) -> Option<CrateId> {
match self { match self {
TypeCtor::Bool TypeCtor::Scalar(_)
| TypeCtor::Char
| TypeCtor::Int(_)
| TypeCtor::Float(_)
| TypeCtor::Str | TypeCtor::Str
| TypeCtor::Never | TypeCtor::Never
| TypeCtor::Slice | TypeCtor::Slice
@ -232,10 +215,7 @@ impl TypeCtor {
pub fn as_generic_def(self) -> Option<GenericDefId> { pub fn as_generic_def(self) -> Option<GenericDefId> {
match self { match self {
TypeCtor::Bool TypeCtor::Scalar(_)
| TypeCtor::Char
| TypeCtor::Int(_)
| TypeCtor::Float(_)
| TypeCtor::Str | TypeCtor::Str
| TypeCtor::Never | TypeCtor::Never
| TypeCtor::Slice | TypeCtor::Slice
@ -741,11 +721,16 @@ impl Ty {
} }
pub fn builtin(builtin: BuiltinType) -> Self { pub fn builtin(builtin: BuiltinType) -> Self {
Ty::simple(match builtin { Ty::simple(match builtin {
BuiltinType::Char => TypeCtor::Char, BuiltinType::Char => TypeCtor::Scalar(Scalar::Char),
BuiltinType::Bool => TypeCtor::Bool, BuiltinType::Bool => TypeCtor::Scalar(Scalar::Bool),
BuiltinType::Str => TypeCtor::Str, BuiltinType::Str => TypeCtor::Str,
BuiltinType::Int(t) => TypeCtor::Int(IntTy::from(t).into()), BuiltinType::Int(t) => TypeCtor::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))),
BuiltinType::Float(t) => TypeCtor::Float(FloatTy::from(t).into()), BuiltinType::Uint(t) => {
TypeCtor::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t)))
}
BuiltinType::Float(t) => {
TypeCtor::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t)))
}
}) })
} }

View file

@ -7,11 +7,8 @@ use std::{iter, sync::Arc};
use arrayvec::ArrayVec; use arrayvec::ArrayVec;
use base_db::CrateId; use base_db::CrateId;
use hir_def::{ use hir_def::{
builtin_type::{IntBitness, Signedness}, lang_item::LangItemTarget, type_ref::Mutability, AssocContainerId, AssocItemId, FunctionId,
lang_item::LangItemTarget, GenericDefId, HasModule, ImplId, Lookup, ModuleId, TraitId,
type_ref::Mutability,
AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule, ImplId, Lookup, ModuleId,
TraitId,
}; };
use hir_expand::name::Name; use hir_expand::name::Name;
use rustc_hash::{FxHashMap, FxHashSet}; use rustc_hash::{FxHashMap, FxHashSet};
@ -19,10 +16,10 @@ use rustc_hash::{FxHashMap, FxHashSet};
use crate::{ use crate::{
autoderef, autoderef,
db::HirDatabase, db::HirDatabase,
primitive::{FloatBitness, FloatTy, IntTy}, primitive::{self, FloatTy, IntTy, UintTy},
utils::all_super_traits, utils::all_super_traits,
ApplicationTy, Canonical, DebruijnIndex, InEnvironment, Substs, TraitEnvironment, TraitRef, Ty, ApplicationTy, Canonical, DebruijnIndex, InEnvironment, Scalar, Substs, TraitEnvironment,
TyKind, TypeCtor, TypeWalk, TraitRef, Ty, TyKind, TypeCtor, TypeWalk,
}; };
/// This is used as a key for indexing impls. /// This is used as a key for indexing impls.
@ -46,59 +43,23 @@ impl TyFingerprint {
} }
pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [
TyFingerprint::Apply(TypeCtor::Int(IntTy { TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I8))),
signedness: Signedness::Unsigned, TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I16))),
bitness: IntBitness::X8, TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I32))),
})), TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I64))),
TyFingerprint::Apply(TypeCtor::Int(IntTy { TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I128))),
signedness: Signedness::Unsigned, TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::Isize))),
bitness: IntBitness::X16, TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U8))),
})), TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U16))),
TyFingerprint::Apply(TypeCtor::Int(IntTy { TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U32))),
signedness: Signedness::Unsigned, TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U64))),
bitness: IntBitness::X32, TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U128))),
})), TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::Usize))),
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,
})),
]; ];
pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [ pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [
TyFingerprint::Apply(TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 })), TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Float(FloatTy::F32))),
TyFingerprint::Apply(TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 })), TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Float(FloatTy::F64))),
]; ];
/// Trait impls defined or available in some crate. /// Trait impls defined or available in some crate.
@ -257,14 +218,19 @@ impl Ty {
TypeCtor::ForeignType(type_alias_id) => { TypeCtor::ForeignType(type_alias_id) => {
return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast())); return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast()));
} }
TypeCtor::Bool => lang_item_crate!("bool"), TypeCtor::Scalar(Scalar::Bool) => lang_item_crate!("bool"),
TypeCtor::Char => lang_item_crate!("char"), TypeCtor::Scalar(Scalar::Char) => lang_item_crate!("char"),
TypeCtor::Float(f) => match f.bitness { TypeCtor::Scalar(Scalar::Float(f)) => match f {
// There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"), FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"),
FloatBitness::X64 => lang_item_crate!("f64", "f64_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!(primitive::int_ty_to_string(t))
}
TypeCtor::Scalar(Scalar::Uint(t)) => {
lang_item_crate!(primitive::uint_ty_to_string(t))
}
TypeCtor::Str => lang_item_crate!("str_alloc", "str"), TypeCtor::Str => lang_item_crate!("str_alloc", "str"),
TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"), TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"),
TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"), TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"),

View file

@ -2,15 +2,17 @@
use hir_def::expr::{ArithOp, BinaryOp, CmpOp}; use hir_def::expr::{ArithOp, BinaryOp, CmpOp};
use super::{InferTy, Ty, TypeCtor}; 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 { pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
match op { 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::Assignment { .. } => Ty::unit(),
BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => match lhs_ty { BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => match lhs_ty {
Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { 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::Unknown,
}, },
Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, 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 { BinaryOp::ArithOp(_) => match rhs_ty {
Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { 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::Unknown,
}, },
Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => rhs_ty, 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 { pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
match op { match op {
BinaryOp::LogicOp(..) => Ty::simple(TypeCtor::Bool), BinaryOp::LogicOp(..) => Ty::simple(TypeCtor::Scalar(Scalar::Bool)),
BinaryOp::Assignment { op: None } => lhs_ty, BinaryOp::Assignment { op: None } => lhs_ty,
BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty { BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty {
Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
TypeCtor::Int(..) TypeCtor::Scalar(_) | TypeCtor::Str => lhs_ty,
| TypeCtor::Float(..)
| TypeCtor::Str
| TypeCtor::Char
| TypeCtor::Bool => lhs_ty,
_ => Ty::Unknown, _ => Ty::Unknown,
}, },
Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, 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::Assignment { op: Some(_) }
| BinaryOp::ArithOp(_) => match lhs_ty { | BinaryOp::ArithOp(_) => match lhs_ty {
Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { 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::Unknown,
}, },
Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty,

View file

@ -3,137 +3,63 @@
//! * during type inference, they can be uncertain (ie, `let x = 92;`) //! * during type inference, they can be uncertain (ie, `let x = 92;`)
//! * they don't belong to any particular crate. //! * they don't belong to any particular crate.
use std::fmt; pub use chalk_ir::{FloatTy, IntTy, UintTy};
pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint};
pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, FloatBitness, IntBitness, Signedness}; pub fn int_ty_to_string(ty: IntTy) -> &'static str {
match ty {
#[derive(Copy, Clone, Eq, PartialEq, Hash)] IntTy::Isize => "isize",
pub struct IntTy { IntTy::I8 => "i8",
pub signedness: Signedness, IntTy::I16 => "i16",
pub bitness: IntBitness, IntTy::I32 => "i32",
} IntTy::I64 => "i64",
IntTy::I128 => "i128",
impl fmt::Debug for IntTy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(self, f)
} }
} }
impl fmt::Display for IntTy { pub fn uint_ty_to_string(ty: UintTy) -> &'static str {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match ty {
write!(f, "{}", self.ty_to_string()) UintTy::Usize => "usize",
UintTy::U8 => "u8",
UintTy::U16 => "u16",
UintTy::U32 => "u32",
UintTy::U64 => "u64",
UintTy::U128 => "u128",
} }
} }
impl IntTy { pub fn float_ty_to_string(ty: FloatTy) -> &'static str {
pub fn isize() -> IntTy { match ty {
IntTy { signedness: Signedness::Signed, bitness: IntBitness::Xsize } FloatTy::F32 => "f32",
} FloatTy::F64 => "f64",
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 u128() -> IntTy {
IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X128 }
}
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",
}
} }
} }
#[derive(Copy, Clone, PartialEq, Eq, Hash)] pub(super) fn int_ty_from_builtin(t: BuiltinInt) -> IntTy {
pub struct FloatTy { match t {
pub bitness: FloatBitness, BuiltinInt::Isize => IntTy::Isize,
} BuiltinInt::I8 => IntTy::I8,
BuiltinInt::I16 => IntTy::I16,
impl fmt::Debug for FloatTy { BuiltinInt::I32 => IntTy::I32,
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { BuiltinInt::I64 => IntTy::I64,
fmt::Display::fmt(self, f) BuiltinInt::I128 => IntTy::I128,
} }
} }
impl fmt::Display for FloatTy { pub(super) fn uint_ty_from_builtin(t: BuiltinUint) -> UintTy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match t {
write!(f, "{}", self.ty_to_string()) BuiltinUint::Usize => UintTy::Usize,
BuiltinUint::U8 => UintTy::U8,
BuiltinUint::U16 => UintTy::U16,
BuiltinUint::U32 => UintTy::U32,
BuiltinUint::U64 => UintTy::U64,
BuiltinUint::U128 => UintTy::U128,
} }
} }
impl FloatTy { pub(super) fn float_ty_from_builtin(t: BuiltinFloat) -> FloatTy {
pub fn f32() -> FloatTy { match t {
FloatTy { bitness: FloatBitness::X32 } BuiltinFloat::F32 => FloatTy::F32,
} BuiltinFloat::F64 => FloatTy::F64,
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",
}
}
}
impl From<BuiltinInt> for IntTy {
fn from(t: BuiltinInt) -> Self {
IntTy { signedness: t.signedness, bitness: t.bitness }
}
}
impl From<BuiltinFloat> for FloatTy {
fn from(t: BuiltinFloat) -> Self {
FloatTy { bitness: t.bitness }
} }
} }

View file

@ -4,7 +4,7 @@
//! conversions. //! conversions.
use chalk_ir::{ use chalk_ir::{
cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData, PlaceholderIndex, Scalar, cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData, PlaceholderIndex,
UniverseIndex, UniverseIndex,
}; };
use chalk_solve::rust_ir; use chalk_solve::rust_ir;
@ -14,10 +14,11 @@ use hir_def::{type_ref::Mutability, AssocContainerId, GenericDefId, Lookup, Type
use crate::{ use crate::{
db::HirDatabase, db::HirDatabase,
primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness}, primitive::UintTy,
traits::{Canonical, Obligation}, traits::{Canonical, Obligation},
ApplicationTy, CallableDefId, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId, 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::*; use super::interner::*;
@ -63,19 +64,7 @@ impl ToChalk for Ty {
chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner) chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner)
} }
TypeCtor::Bool => chalk_ir::TyKind::Scalar(Scalar::Bool).intern(&Interner), TypeCtor::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).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::Tuple { cardinality } => { TypeCtor::Tuple { cardinality } => {
let substitution = apply_ty.parameters.to_chalk(db); let substitution = apply_ty.parameters.to_chalk(db);
@ -219,22 +208,7 @@ impl ToChalk for Ty {
apply_ty_from_chalk(db, TypeCtor::OpaqueType(from_chalk(db, opaque_type_id)), subst) 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) => Ty::simple(TypeCtor::Scalar(scalar)),
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(Scalar::Float(chalk_ir::FloatTy::F64)) => {
Ty::simple(TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }))
}
chalk_ir::TyKind::Tuple(cardinality, subst) => { chalk_ir::TyKind::Tuple(cardinality, subst) => {
apply_ty_from_chalk(db, TypeCtor::Tuple { cardinality: cardinality as u16 }, subst) apply_ty_from_chalk(db, TypeCtor::Tuple { cardinality: cardinality as u16 }, subst)
} }
@ -292,8 +266,7 @@ fn ref_to_chalk(
/// fake constant here, because Chalks built-in logic may expect it to be there. /// fake constant here, because Chalks built-in logic may expect it to be there.
fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> { fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> {
let arg = subst[0].clone().to_chalk(db); let arg = subst[0].clone().to_chalk(db);
let usize_ty = let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner);
chalk_ir::TyKind::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)).intern(&Interner);
let const_ = chalk_ir::ConstData { let const_ = chalk_ir::ConstData {
ty: usize_ty, ty: usize_ty,
value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }), value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }),
@ -364,55 +337,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 { impl ToChalk for Mutability {
type Chalk = chalk_ir::Mutability; type Chalk = chalk_ir::Mutability;
fn to_chalk(self, _db: &dyn HirDatabase) -> Self::Chalk { fn to_chalk(self, _db: &dyn HirDatabase) -> Self::Chalk {