use super::{Expr, Ident, Lifetime, Mutability, NodeId, Path, TypeBound};
use crate::lexer::Span;
#[derive(Debug, Clone, PartialEq)]
pub struct Type {
pub kind: TypeKind,
pub span: Span,
pub id: NodeId,
}
impl Type {
pub fn new(kind: TypeKind, span: Span) -> Self {
Self {
kind,
span,
id: NodeId::DUMMY,
}
}
pub fn inferred(span: Span) -> Self {
Self::new(TypeKind::Infer, span)
}
pub fn unit(span: Span) -> Self {
Self::new(TypeKind::Tuple(Vec::new()), span)
}
pub fn never(span: Span) -> Self {
Self::new(TypeKind::Never, span)
}
pub fn is_unit(&self) -> bool {
matches!(&self.kind, TypeKind::Tuple(v) if v.is_empty())
}
pub fn is_never(&self) -> bool {
matches!(self.kind, TypeKind::Never)
}
pub fn is_inferred(&self) -> bool {
matches!(self.kind, TypeKind::Infer)
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum TypeKind {
Path(Path),
Never,
Infer,
Tuple(Vec<Type>),
Array { elem: Box<Type>, len: Box<Expr> },
Slice(Box<Type>),
Ref {
lifetime: Option<Lifetime>,
mutability: Mutability,
ty: Box<Type>,
},
Ptr {
mutability: Mutability,
ty: Box<Type>,
},
BareFn {
is_unsafe: bool,
is_extern: bool,
abi: Option<String>,
params: Vec<BareFnParam>,
return_ty: Option<Box<Type>>,
is_variadic: bool,
},
FnTrait {
kind: FnTraitKind,
params: Vec<Type>,
return_ty: Option<Box<Type>>,
},
TraitObject {
bounds: Vec<TypeBound>,
lifetime: Option<Lifetime>,
},
ImplTrait { bounds: Vec<TypeBound> },
Paren(Box<Type>),
Macro {
path: Path,
tokens: Vec<super::TokenTree>,
},
Error,
WithEffect { ty: Box<Type>, effects: Vec<Path> },
Neural { input: Box<Type>, output: Box<Type> },
Optional(Box<Type>),
Result { ok: Box<Type>, err: Box<Type> },
}
#[derive(Debug, Clone, PartialEq)]
pub struct BareFnParam {
pub name: Option<Ident>,
pub ty: Box<Type>,
pub span: Span,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FnTraitKind {
Fn,
FnMut,
FnOnce,
}
impl FnTraitKind {
pub fn as_str(&self) -> &'static str {
match self {
FnTraitKind::Fn => "Fn",
FnTraitKind::FnMut => "FnMut",
FnTraitKind::FnOnce => "FnOnce",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum PrimitiveType {
I8,
I16,
I32,
I64,
I128,
Isize,
U8,
U16,
U32,
U64,
U128,
Usize,
F16,
F32,
F64,
Bool,
Char,
Str,
}
impl PrimitiveType {
pub fn from_str(s: &str) -> Option<Self> {
match s {
"i8" => Some(PrimitiveType::I8),
"i16" => Some(PrimitiveType::I16),
"i32" => Some(PrimitiveType::I32),
"i64" => Some(PrimitiveType::I64),
"i128" => Some(PrimitiveType::I128),
"isize" => Some(PrimitiveType::Isize),
"u8" => Some(PrimitiveType::U8),
"u16" => Some(PrimitiveType::U16),
"u32" => Some(PrimitiveType::U32),
"u64" => Some(PrimitiveType::U64),
"u128" => Some(PrimitiveType::U128),
"usize" => Some(PrimitiveType::Usize),
"f16" => Some(PrimitiveType::F16),
"f32" => Some(PrimitiveType::F32),
"f64" => Some(PrimitiveType::F64),
"bool" => Some(PrimitiveType::Bool),
"char" => Some(PrimitiveType::Char),
"str" => Some(PrimitiveType::Str),
_ => None,
}
}
pub fn as_str(&self) -> &'static str {
match self {
PrimitiveType::I8 => "i8",
PrimitiveType::I16 => "i16",
PrimitiveType::I32 => "i32",
PrimitiveType::I64 => "i64",
PrimitiveType::I128 => "i128",
PrimitiveType::Isize => "isize",
PrimitiveType::U8 => "u8",
PrimitiveType::U16 => "u16",
PrimitiveType::U32 => "u32",
PrimitiveType::U64 => "u64",
PrimitiveType::U128 => "u128",
PrimitiveType::Usize => "usize",
PrimitiveType::F16 => "f16",
PrimitiveType::F32 => "f32",
PrimitiveType::F64 => "f64",
PrimitiveType::Bool => "bool",
PrimitiveType::Char => "char",
PrimitiveType::Str => "str",
}
}
pub fn is_integer(&self) -> bool {
matches!(
self,
PrimitiveType::I8
| PrimitiveType::I16
| PrimitiveType::I32
| PrimitiveType::I64
| PrimitiveType::I128
| PrimitiveType::Isize
| PrimitiveType::U8
| PrimitiveType::U16
| PrimitiveType::U32
| PrimitiveType::U64
| PrimitiveType::U128
| PrimitiveType::Usize
)
}
pub fn is_signed(&self) -> bool {
matches!(
self,
PrimitiveType::I8
| PrimitiveType::I16
| PrimitiveType::I32
| PrimitiveType::I64
| PrimitiveType::I128
| PrimitiveType::Isize
)
}
pub fn is_float(&self) -> bool {
matches!(
self,
PrimitiveType::F16 | PrimitiveType::F32 | PrimitiveType::F64
)
}
}