From 504c8c7c2e371f2adccbc292ad09af2b31e05787 Mon Sep 17 00:00:00 2001 From: yanchith Date: Fri, 22 Mar 2019 10:09:35 +0100 Subject: Refactor primitive types into more orthogonal representation --- crates/ra_hir/src/expr.rs | 10 +- crates/ra_hir/src/ty/infer.rs | 15 ++- crates/ra_hir/src/ty/lower.rs | 8 +- crates/ra_hir/src/ty/primitive.rs | 266 +++++++++++++++++++------------------- 4 files changed, 155 insertions(+), 144 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 486314cc5..0fadab560 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -14,7 +14,7 @@ use crate::{ name::AsName, type_ref::{Mutability, TypeRef}, }; -use crate::{ path::GenericArgs, ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy}}; +use crate::{ path::GenericArgs, ty::primitive::{IntTy, UncertainIntTy, FloatTy, UncertainFloatTy}}; pub use self::scope::{ExprScopes, ScopesWithSourceMap, ScopeEntryWithSyntax}; @@ -723,7 +723,8 @@ impl ExprCollector { let lit = match child.flavor() { LiteralFlavor::IntNumber { suffix } => { - let known_name = suffix.and_then(|it| UncertainIntTy::from_suffix(&it)); + let known_name = suffix + .and_then(|it| IntTy::from_suffix(&it).map(UncertainIntTy::Known)); Literal::Int( Default::default(), @@ -731,7 +732,8 @@ impl ExprCollector { ) } LiteralFlavor::FloatNumber { suffix } => { - let known_name = suffix.and_then(|it| UncertainFloatTy::from_suffix(&it)); + let known_name = suffix + .and_then(|it| FloatTy::from_suffix(&it).map(UncertainFloatTy::Known)); Literal::Float( Default::default(), @@ -741,7 +743,7 @@ impl ExprCollector { LiteralFlavor::ByteString => Literal::ByteString(Default::default()), LiteralFlavor::String => Literal::String(Default::default()), LiteralFlavor::Byte => { - Literal::Int(Default::default(), UncertainIntTy::Unsigned(UintTy::U8)) + Literal::Int(Default::default(), UncertainIntTy::Known(IntTy::u8())) } LiteralFlavor::Bool => Literal::Bool(Default::default()), LiteralFlavor::Char => Literal::Char(Default::default()), diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index bf42befbb..7cf465266 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -990,7 +990,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { match &inner_ty { Ty::Apply(a_ty) => match a_ty.ctor { TypeCtor::Int(primitive::UncertainIntTy::Unknown) - | TypeCtor::Int(primitive::UncertainIntTy::Signed(..)) + | TypeCtor::Int(primitive::UncertainIntTy::Known( + primitive::IntTy { + signedness: primitive::Signedness::Signed, + .. + }, + )) | TypeCtor::Float(..) => inner_ty, _ => Ty::Unknown, }, @@ -1064,8 +1069,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str)) } Literal::ByteString(..) => { - let byte_type = Ty::simple(TypeCtor::Int(primitive::UncertainIntTy::Unsigned( - primitive::UintTy::U8, + let byte_type = Ty::simple(TypeCtor::Int(primitive::UncertainIntTy::Known( + primitive::IntTy::u8(), ))); let slice_type = Ty::apply_one(TypeCtor::Slice, byte_type); Ty::apply_one(TypeCtor::Ref(Mutability::Shared), slice_type) @@ -1208,10 +1213,10 @@ impl InferTy { match self { InferTy::TypeVar(..) => Ty::Unknown, InferTy::IntVar(..) => { - Ty::simple(TypeCtor::Int(primitive::UncertainIntTy::Signed(primitive::IntTy::I32))) + Ty::simple(TypeCtor::Int(primitive::UncertainIntTy::Known(primitive::IntTy::i32()))) } InferTy::FloatVar(..) => Ty::simple(TypeCtor::Float( - primitive::UncertainFloatTy::Known(primitive::FloatTy::F64), + primitive::UncertainFloatTy::Known(primitive::FloatTy::f64()), )), } } diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 72b1234bf..7f9af307b 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -61,10 +61,10 @@ impl Ty { pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Self { if let Some(name) = path.as_ident() { // TODO handle primitive type names in resolver as well? - if let Some(int_ty) = primitive::UncertainIntTy::from_type_name(name) { - return Ty::simple(TypeCtor::Int(int_ty)); - } else if let Some(float_ty) = primitive::UncertainFloatTy::from_type_name(name) { - return Ty::simple(TypeCtor::Float(float_ty)); + if let Some(int_ty) = primitive::IntTy::from_type_name(name) { + return Ty::simple(TypeCtor::Int(primitive::UncertainIntTy::Known(int_ty))); + } else if let Some(float_ty) = primitive::FloatTy::from_type_name(name) { + return Ty::simple(TypeCtor::Float(primitive::UncertainFloatTy::Known(float_ty))); } else if let Some(known) = name.as_known_name() { match known { KnownName::Bool => return Ty::simple(TypeCtor::Bool), diff --git a/crates/ra_hir/src/ty/primitive.rs b/crates/ra_hir/src/ty/primitive.rs index 421f7e980..b37326db7 100644 --- a/crates/ra_hir/src/ty/primitive.rs +++ b/crates/ra_hir/src/ty/primitive.rs @@ -2,61 +2,49 @@ use std::fmt; use crate::{Name, KnownName}; -#[derive(Debug, Clone, Eq, PartialEq, Hash, Copy)] -pub enum UncertainIntTy { - Unknown, - Unsigned(UintTy), - Signed(IntTy), +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +pub enum Signedness { + Signed, + Unsigned, } -impl UncertainIntTy { - pub(crate) fn from_type_name(name: &Name) -> Option { - if let Some(ty) = IntTy::from_type_name(name) { - Some(UncertainIntTy::Signed(ty)) - } else if let Some(ty) = UintTy::from_type_name(name) { - Some(UncertainIntTy::Unsigned(ty)) - } else { - None - } - } +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +pub enum IntBitness { + Xsize, + X8, + X16, + X32, + X64, + X128, +} - pub(crate) fn from_suffix(suffix: &str) -> Option { - if let Some(ty) = IntTy::from_suffix(suffix) { - Some(UncertainIntTy::Signed(ty)) - } else if let Some(ty) = UintTy::from_suffix(suffix) { - Some(UncertainIntTy::Unsigned(ty)) - } else { - None - } - } +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +pub enum FloatBitness { + X32, + X64, +} + +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +pub enum UncertainIntTy { + Unknown, + Known(IntTy), } impl fmt::Display for UncertainIntTy { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { UncertainIntTy::Unknown => write!(f, "{{integer}}"), - UncertainIntTy::Signed(ty) => write!(f, "{}", ty), - UncertainIntTy::Unsigned(ty) => write!(f, "{}", ty), + UncertainIntTy::Known(ty) => write!(f, "{}", ty), } } } -#[derive(Debug, Clone, Eq, PartialEq, Hash, Copy)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub enum UncertainFloatTy { Unknown, Known(FloatTy), } -impl UncertainFloatTy { - pub(crate) fn from_type_name(name: &Name) -> Option { - FloatTy::from_type_name(name).map(UncertainFloatTy::Known) - } - - pub(crate) fn from_suffix(suffix: &str) -> Option { - FloatTy::from_suffix(suffix).map(UncertainFloatTy::Known) - } -} - impl fmt::Display for UncertainFloatTy { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { @@ -66,14 +54,10 @@ impl fmt::Display for UncertainFloatTy { } } -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)] -pub enum IntTy { - Isize, - I8, - I16, - I32, - I64, - I128, +#[derive(Copy, Clone, Eq, PartialEq, Hash)] +pub struct IntTy { + pub signedness: Signedness, + pub bitness: IntBitness, } impl fmt::Debug for IntTy { @@ -84,104 +68,116 @@ impl fmt::Debug for IntTy { impl fmt::Display for IntTy { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let s = match *self { - IntTy::Isize => "isize", - IntTy::I8 => "i8", - IntTy::I16 => "i16", - IntTy::I32 => "i32", - IntTy::I64 => "i64", - IntTy::I128 => "i128", - }; - write!(f, "{}", s) + write!(f, "{}", self.ty_to_string()) } } impl IntTy { - fn from_type_name(name: &Name) -> Option { - match name.as_known_name()? { - KnownName::Isize => Some(IntTy::Isize), - KnownName::I8 => Some(IntTy::I8), - KnownName::I16 => Some(IntTy::I16), - KnownName::I32 => Some(IntTy::I32), - KnownName::I64 => Some(IntTy::I64), - KnownName::I128 => Some(IntTy::I128), - _ => None, - } + pub fn isize() -> IntTy { + IntTy { signedness: Signedness::Signed, bitness: IntBitness::Xsize } } - fn from_suffix(suffix: &str) -> Option { - match suffix { - "isize" => Some(IntTy::Isize), - "i8" => Some(IntTy::I8), - "i16" => Some(IntTy::I16), - "i32" => Some(IntTy::I32), - "i64" => Some(IntTy::I64), - "i128" => Some(IntTy::I128), - _ => None, - } + pub fn i8() -> IntTy { + IntTy { signedness: Signedness::Signed, bitness: IntBitness::X8 } } -} -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)] -pub enum UintTy { - Usize, - U8, - U16, - U32, - U64, - U128, -} + pub fn i16() -> IntTy { + IntTy { signedness: Signedness::Signed, bitness: IntBitness::X16 } + } -impl fmt::Display for UintTy { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let s = match *self { - UintTy::Usize => "usize", - UintTy::U8 => "u8", - UintTy::U16 => "u16", - UintTy::U32 => "u32", - UintTy::U64 => "u64", - UintTy::U128 => "u128", - }; - write!(f, "{}", s) + pub fn i32() -> IntTy { + IntTy { signedness: Signedness::Signed, bitness: IntBitness::X32 } } -} -impl UintTy { - fn from_type_name(name: &Name) -> Option { + 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(crate) 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", + } + } + + pub(crate) fn from_type_name(name: &Name) -> Option { match name.as_known_name()? { - KnownName::Usize => Some(UintTy::Usize), - KnownName::U8 => Some(UintTy::U8), - KnownName::U16 => Some(UintTy::U16), - KnownName::U32 => Some(UintTy::U32), - KnownName::U64 => Some(UintTy::U64), - KnownName::U128 => Some(UintTy::U128), + KnownName::Isize => Some(IntTy::isize()), + KnownName::I8 => Some(IntTy::i8()), + KnownName::I16 => Some(IntTy::i16()), + KnownName::I32 => Some(IntTy::i32()), + KnownName::I64 => Some(IntTy::i64()), + KnownName::I128 => Some(IntTy::i128()), + KnownName::Usize => Some(IntTy::usize()), + KnownName::U8 => Some(IntTy::u8()), + KnownName::U16 => Some(IntTy::u16()), + KnownName::U32 => Some(IntTy::u32()), + KnownName::U64 => Some(IntTy::u64()), + KnownName::U128 => Some(IntTy::u128()), _ => None, } } - fn from_suffix(suffix: &str) -> Option { + pub(crate) fn from_suffix(suffix: &str) -> Option { match suffix { - "usize" => Some(UintTy::Usize), - "u8" => Some(UintTy::U8), - "u16" => Some(UintTy::U16), - "u32" => Some(UintTy::U32), - "u64" => Some(UintTy::U64), - "u128" => Some(UintTy::U128), + "isize" => Some(IntTy::isize()), + "i8" => Some(IntTy::i8()), + "i16" => Some(IntTy::i16()), + "i32" => Some(IntTy::i32()), + "i64" => Some(IntTy::i64()), + "i128" => Some(IntTy::i128()), + "usize" => Some(IntTy::usize()), + "u8" => Some(IntTy::u8()), + "u16" => Some(IntTy::u16()), + "u32" => Some(IntTy::u32()), + "u64" => Some(IntTy::u64()), + "u128" => Some(IntTy::u128()), _ => None, } } } -impl fmt::Debug for UintTy { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(self, f) - } -} - -#[derive(Clone, PartialEq, Eq, Hash, Copy, PartialOrd, Ord)] -pub enum FloatTy { - F32, - F64, +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +pub struct FloatTy { + pub bitness: FloatBitness, } impl fmt::Debug for FloatTy { @@ -197,25 +193,33 @@ impl fmt::Display for FloatTy { } impl FloatTy { - pub fn ty_to_string(self) -> &'static str { - match self { - FloatTy::F32 => "f32", - FloatTy::F64 => "f64", + pub fn f32() -> FloatTy { + FloatTy { bitness: FloatBitness::X32 } + } + + pub fn f64() -> FloatTy { + FloatTy { bitness: FloatBitness::X64 } + } + + pub(crate) fn ty_to_string(self) -> &'static str { + match self.bitness { + FloatBitness::X32 => "f32", + FloatBitness::X64 => "f64", } } - fn from_type_name(name: &Name) -> Option { + pub(crate) fn from_type_name(name: &Name) -> Option { match name.as_known_name()? { - KnownName::F32 => Some(FloatTy::F32), - KnownName::F64 => Some(FloatTy::F64), + KnownName::F32 => Some(FloatTy::f32()), + KnownName::F64 => Some(FloatTy::f64()), _ => None, } } - fn from_suffix(suffix: &str) -> Option { + pub(crate) fn from_suffix(suffix: &str) -> Option { match suffix { - "f32" => Some(FloatTy::F32), - "f64" => Some(FloatTy::F64), + "f32" => Some(FloatTy::f32()), + "f64" => Some(FloatTy::f64()), _ => None, } } -- cgit v1.2.3