//! This module defines built-in types. //! //! A peculiarity of built-in types is that they are always available and are //! not associated with any particular crate. use std::fmt; use hir_expand::name::{name, AsName, Name}; /// Different signed int types. #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum BuiltinInt { Isize, I8, I16, I32, I64, I128, } /// Different unsigned int types. #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum BuiltinUint { Usize, U8, U16, U32, U64, U128, } #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum BuiltinFloat { F32, F64, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinType { Char, Bool, Str, Int(BuiltinInt), Uint(BuiltinUint), Float(BuiltinFloat), } impl BuiltinType { #[rustfmt::skip] pub const ALL: &'static [(Name, BuiltinType)] = &[ (name![char], BuiltinType::Char), (name![bool], BuiltinType::Bool), (name![str], BuiltinType::Str), (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::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)), ]; } impl AsName for BuiltinType { fn as_name(&self) -> Name { match self { BuiltinType::Char => name![char], BuiltinType::Bool => name![bool], BuiltinType::Str => name![str], 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::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], }, } } } impl fmt::Display for BuiltinType { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let type_name = self.as_name(); type_name.fmt(f) } } #[rustfmt::skip] impl BuiltinInt { pub fn from_suffix(suffix: &str) -> Option { let res = match suffix { "isize" => Self::Isize, "i8" => Self::I8, "i16" => Self::I16, "i32" => Self::I32, "i64" => Self::I64, "i128" => Self::I128, _ => return None, }; Some(res) } } #[rustfmt::skip] impl BuiltinUint { pub fn from_suffix(suffix: &str) -> Option { let res = match suffix { "usize" => Self::Usize, "u8" => Self::U8, "u16" => Self::U16, "u32" => Self::U32, "u64" => Self::U64, "u128" => Self::U128, _ => return None, }; Some(res) } } #[rustfmt::skip] impl BuiltinFloat { pub fn from_suffix(suffix: &str) -> Option { let res = match suffix { "f32" => BuiltinFloat::F32, "f64" => BuiltinFloat::F64, _ => return None, }; Some(res) } }