Introduce TypeCtor::Scalar
This commit is contained in:
parent
2a4076c14d
commit
5183c9f083
@ -32,8 +32,8 @@
|
||||
method_resolution,
|
||||
traits::{FnTrait, Solution, SolutionVariables},
|
||||
ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate,
|
||||
InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, Ty,
|
||||
TyDefId, TyKind, TypeCtor,
|
||||
InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment,
|
||||
Ty, TyDefId, TyKind, TypeCtor,
|
||||
};
|
||||
use rustc_hash::FxHashSet;
|
||||
use stdx::{format_to, impl_from};
|
||||
@ -1553,7 +1553,10 @@ pub fn is_unit(&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 {
|
||||
|
@ -24,7 +24,7 @@
|
||||
use crate::{
|
||||
adt::StructKind,
|
||||
body::{Body, BodySourceMap, Expander, LabelSource, PatPtr, SyntheticSyntax},
|
||||
builtin_type::{BuiltinFloat, BuiltinInt},
|
||||
builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint},
|
||||
db::DefDatabase,
|
||||
diagnostics::{InactiveCode, MacroError, UnresolvedProcMacro},
|
||||
expr::{
|
||||
@ -1065,11 +1065,16 @@ impl From<ast::LiteralKind> for Literal {
|
||||
fn from(ast_lit_kind: ast::LiteralKind) -> Self {
|
||||
match ast_lit_kind {
|
||||
LiteralKind::IntNumber(lit) => {
|
||||
if let Some(float_suffix) = lit.suffix().and_then(BuiltinFloat::from_suffix) {
|
||||
return Literal::Float(Default::default(), Some(float_suffix));
|
||||
if let builtin @ Some(_) = lit.suffix().and_then(BuiltinFloat::from_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) => {
|
||||
let ty = lit.suffix().and_then(|it| BuiltinFloat::from_suffix(&it));
|
||||
@ -1077,7 +1082,7 @@ fn from(ast_lit_kind: ast::LiteralKind) -> Self {
|
||||
}
|
||||
LiteralKind::ByteString(_) => Literal::ByteString(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::Char => Literal::Char(Default::default()),
|
||||
}
|
||||
|
@ -6,38 +6,32 @@
|
||||
use std::fmt;
|
||||
|
||||
use hir_expand::name::{name, AsName, Name};
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub enum Signedness {
|
||||
Signed,
|
||||
Unsigned,
|
||||
/// Different signed int types.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum BuiltinInt {
|
||||
Isize,
|
||||
I8,
|
||||
I16,
|
||||
I32,
|
||||
I64,
|
||||
I128,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub enum IntBitness {
|
||||
Xsize,
|
||||
X8,
|
||||
X16,
|
||||
X32,
|
||||
X64,
|
||||
X128,
|
||||
/// Different unsigned int types.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum BuiltinUint {
|
||||
Usize,
|
||||
U8,
|
||||
U16,
|
||||
U32,
|
||||
U64,
|
||||
U128,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub enum FloatBitness {
|
||||
X32,
|
||||
X64,
|
||||
}
|
||||
|
||||
#[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(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum BuiltinFloat {
|
||||
F32,
|
||||
F64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
@ -46,6 +40,7 @@ pub enum BuiltinType {
|
||||
Bool,
|
||||
Str,
|
||||
Int(BuiltinInt),
|
||||
Uint(BuiltinUint),
|
||||
Float(BuiltinFloat),
|
||||
}
|
||||
|
||||
@ -56,19 +51,19 @@ impl BuiltinType {
|
||||
(name![bool], BuiltinType::Bool),
|
||||
(name![str], BuiltinType::Str),
|
||||
|
||||
(name![isize], BuiltinType::Int(BuiltinInt::ISIZE)),
|
||||
(name![isize], BuiltinType::Int(BuiltinInt::Isize)),
|
||||
(name![i8], BuiltinType::Int(BuiltinInt::I8)),
|
||||
(name![i16], BuiltinType::Int(BuiltinInt::I16)),
|
||||
(name![i32], BuiltinType::Int(BuiltinInt::I32)),
|
||||
(name![i64], BuiltinType::Int(BuiltinInt::I64)),
|
||||
(name![i128], BuiltinType::Int(BuiltinInt::I128)),
|
||||
|
||||
(name![usize], BuiltinType::Int(BuiltinInt::USIZE)),
|
||||
(name![u8], BuiltinType::Int(BuiltinInt::U8)),
|
||||
(name![u16], BuiltinType::Int(BuiltinInt::U16)),
|
||||
(name![u32], BuiltinType::Int(BuiltinInt::U32)),
|
||||
(name![u64], BuiltinType::Int(BuiltinInt::U64)),
|
||||
(name![u128], BuiltinType::Int(BuiltinInt::U128)),
|
||||
(name![usize], BuiltinType::Uint(BuiltinUint::Usize)),
|
||||
(name![u8], BuiltinType::Uint(BuiltinUint::U8)),
|
||||
(name![u16], BuiltinType::Uint(BuiltinUint::U16)),
|
||||
(name![u32], BuiltinType::Uint(BuiltinUint::U32)),
|
||||
(name![u64], BuiltinType::Uint(BuiltinUint::U64)),
|
||||
(name![u128], BuiltinType::Uint(BuiltinUint::U128)),
|
||||
|
||||
(name![f32], BuiltinType::Float(BuiltinFloat::F32)),
|
||||
(name![f64], BuiltinType::Float(BuiltinFloat::F64)),
|
||||
@ -81,24 +76,25 @@ fn as_name(&self) -> Name {
|
||||
BuiltinType::Char => name![char],
|
||||
BuiltinType::Bool => name![bool],
|
||||
BuiltinType::Str => name![str],
|
||||
BuiltinType::Int(BuiltinInt { signedness, bitness }) => match (signedness, bitness) {
|
||||
(Signedness::Signed, IntBitness::Xsize) => name![isize],
|
||||
(Signedness::Signed, IntBitness::X8) => name![i8],
|
||||
(Signedness::Signed, IntBitness::X16) => name![i16],
|
||||
(Signedness::Signed, IntBitness::X32) => name![i32],
|
||||
(Signedness::Signed, IntBitness::X64) => name![i64],
|
||||
(Signedness::Signed, IntBitness::X128) => 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::Int(it) => match it {
|
||||
BuiltinInt::Isize => name![isize],
|
||||
BuiltinInt::I8 => name![i8],
|
||||
BuiltinInt::I16 => name![i16],
|
||||
BuiltinInt::I32 => name![i32],
|
||||
BuiltinInt::I64 => name![i64],
|
||||
BuiltinInt::I128 => name![i128],
|
||||
},
|
||||
BuiltinType::Float(BuiltinFloat { bitness }) => match bitness {
|
||||
FloatBitness::X32 => name![f32],
|
||||
FloatBitness::X64 => name![f64],
|
||||
BuiltinType::Uint(it) => match it {
|
||||
BuiltinUint::Usize => name![usize],
|
||||
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 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
|
||||
#[rustfmt::skip]
|
||||
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> {
|
||||
let res = match suffix {
|
||||
"isize" => Self::ISIZE,
|
||||
"isize" => Self::Isize,
|
||||
"i8" => Self::I8,
|
||||
"i16" => Self::I16,
|
||||
"i32" => Self::I32,
|
||||
"i64" => Self::I64,
|
||||
"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,
|
||||
"u16" => Self::U16,
|
||||
"u32" => Self::U32,
|
||||
@ -152,9 +143,6 @@ pub fn from_suffix(suffix: &str) -> Option<BuiltinInt> {
|
||||
|
||||
#[rustfmt::skip]
|
||||
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> {
|
||||
let res = match suffix {
|
||||
"f32" => BuiltinFloat::F32,
|
||||
|
@ -17,7 +17,7 @@
|
||||
use syntax::ast::RangeOp;
|
||||
|
||||
use crate::{
|
||||
builtin_type::{BuiltinFloat, BuiltinInt},
|
||||
builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint},
|
||||
path::{GenericArgs, Path},
|
||||
type_ref::{Mutability, Rawness, TypeRef},
|
||||
BlockId,
|
||||
@ -43,6 +43,7 @@ pub enum Literal {
|
||||
Char(char),
|
||||
Bool(bool),
|
||||
Int(u64, Option<BuiltinInt>),
|
||||
Uint(u64, Option<BuiltinUint>),
|
||||
Float(u64, Option<BuiltinFloat>), // FIXME: f64 is not Eq
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,8 @@
|
||||
|
||||
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 @@ fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
|
||||
}
|
||||
|
||||
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();
|
||||
|
@ -41,7 +41,7 @@
|
||||
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 @@ fn to_inner(self) -> unify::TypeVarId {
|
||||
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),
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
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 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 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
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 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
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 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
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 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
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 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
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 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
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 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
);
|
||||
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 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
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(),
|
||||
},
|
||||
},
|
||||
|
@ -8,8 +8,8 @@
|
||||
|
||||
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 @@ pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -
|
||||
| (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
|
||||
|
@ -38,7 +38,7 @@ macro_rules! eprintln {
|
||||
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 @@ pub fn num_ty_params(self, db: &dyn HirDatabase) -> usize {
|
||||
|
||||
pub fn krate(self, db: &dyn HirDatabase) -> Option<CrateId> {
|
||||
match self {
|
||||
TypeCtor::Bool
|
||||
| TypeCtor::Char
|
||||
| TypeCtor::Int(_)
|
||||
| TypeCtor::Float(_)
|
||||
TypeCtor::Scalar(_)
|
||||
| TypeCtor::Str
|
||||
| TypeCtor::Never
|
||||
| TypeCtor::Slice
|
||||
@ -232,10 +227,7 @@ pub fn krate(self, db: &dyn HirDatabase) -> Option<CrateId> {
|
||||
|
||||
pub fn as_generic_def(self) -> Option<GenericDefId> {
|
||||
match self {
|
||||
TypeCtor::Bool
|
||||
| TypeCtor::Char
|
||||
| TypeCtor::Int(_)
|
||||
| TypeCtor::Float(_)
|
||||
TypeCtor::Scalar(_)
|
||||
| TypeCtor::Str
|
||||
| TypeCtor::Never
|
||||
| TypeCtor::Slice
|
||||
@ -741,11 +733,12 @@ pub fn fn_ptr(sig: FnSig) -> Self {
|
||||
}
|
||||
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())),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -7,11 +7,8 @@
|
||||
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 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 @@ pub(crate) fn for_impl(ty: &Ty) -> Option<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 @@ macro_rules! lang_item_crate {
|
||||
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"),
|
||||
|
@ -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,
|
||||
|
@ -5,18 +5,28 @@
|
||||
|
||||
use std::fmt;
|
||||
|
||||
pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, FloatBitness, IntBitness, Signedness};
|
||||
pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint};
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct IntTy {
|
||||
pub signedness: Signedness,
|
||||
pub bitness: IntBitness,
|
||||
/// 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 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
}
|
||||
|
||||
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 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",
|
||||
match self {
|
||||
IntTy::Isize => "isize",
|
||||
IntTy::I8 => "i8",
|
||||
IntTy::I16 => "i16",
|
||||
IntTy::I32 => "i32",
|
||||
IntTy::I64 => "i64",
|
||||
IntTy::I128 => "i128",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct FloatTy {
|
||||
pub bitness: FloatBitness,
|
||||
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 {
|
||||
UintTy::Usize => "usize",
|
||||
UintTy::U8 => "u8",
|
||||
UintTy::U16 => "u16",
|
||||
UintTy::U32 => "u32",
|
||||
UintTy::U64 => "u64",
|
||||
UintTy::U128 => "u128",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum FloatTy {
|
||||
F32,
|
||||
F64,
|
||||
}
|
||||
|
||||
impl fmt::Debug for FloatTy {
|
||||
@ -110,30 +86,45 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
}
|
||||
|
||||
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<BuiltinInt> 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<BuiltinUint> 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<BuiltinFloat> for FloatTy {
|
||||
fn from(t: BuiltinFloat) -> Self {
|
||||
FloatTy { bitness: t.bitness }
|
||||
match t {
|
||||
BuiltinFloat::F32 => Self::F32,
|
||||
BuiltinFloat::F64 => Self::F64,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 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 @@ fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> {
|
||||
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 @@ fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self {
|
||||
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(Scalar::Float(chalk_ir::FloatTy::F64)) => {
|
||||
Ty::simple(TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }))
|
||||
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(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<Interner> {
|
||||
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 @@ fn from_chalk(
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
Loading…
Reference in New Issue
Block a user