1015: Change primitive integers to have signedness and bitness r=matklad a=yanchith

Fixes #1004 

This creates enums: `Signedness`, `IntBitness` and `FloatBitness`, and condenses `UintTy` with `IntTy`, making use of the created enums. `FloatTy` is also changed from an enum into a struct containing `FloatBitness`.

`UncertainIntTy` and `UncertainFloatTy` now look much more similar.

`Ord` was removed from the types because `{u,i}size` aren't easily orderable with the rest. Fortunately this wasn't depended on anywhere.

Co-authored-by: yanchith <yanchi.toth@gmail.com>
This commit is contained in:
bors[bot] 2019-03-22 12:27:54 +00:00
commit 6bc09e2ff8
4 changed files with 162 additions and 151 deletions

View file

@ -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()),

View file

@ -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()),
)),
}
}

View file

@ -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),

View file

@ -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<UncertainIntTy> {
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<UncertainIntTy> {
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<UncertainFloatTy> {
FloatTy::from_type_name(name).map(UncertainFloatTy::Known)
}
pub(crate) fn from_suffix(suffix: &str) -> Option<UncertainFloatTy> {
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<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(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<IntTy> {
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),
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<IntTy> {
pub(crate) fn from_suffix(suffix: &str) -> Option<IntTy> {
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),
"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,
}
}
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
pub enum UintTy {
Usize,
U8,
U16,
U32,
U64,
U128,
}
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)
}
}
impl UintTy {
fn from_type_name(name: &Name) -> Option<UintTy> {
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),
_ => None,
}
}
fn from_suffix(suffix: &str) -> Option<UintTy> {
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),
_ => 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<FloatTy> {
pub(crate) fn from_type_name(name: &Name) -> Option<FloatTy> {
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<FloatTy> {
pub(crate) fn from_suffix(suffix: &str) -> Option<FloatTy> {
match suffix {
"f32" => Some(FloatTy::F32),
"f64" => Some(FloatTy::F64),
"f32" => Some(FloatTy::f32()),
"f64" => Some(FloatTy::f64()),
_ => None,
}
}