hir_def/
builtin_type.rs

1//! This module defines built-in types.
2//!
3//! A peculiarity of built-in types is that they are always available and are
4//! not associated with any particular crate.
5
6use std::fmt;
7
8use hir_expand::name::{AsName, Name};
9use intern::{Symbol, sym};
10/// Different signed int types.
11#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
12pub enum BuiltinInt {
13    Isize,
14    I8,
15    I16,
16    I32,
17    I64,
18    I128,
19}
20
21/// Different unsigned int types.
22#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
23pub enum BuiltinUint {
24    Usize,
25    U8,
26    U16,
27    U32,
28    U64,
29    U128,
30}
31
32#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
33pub enum BuiltinFloat {
34    F16,
35    F32,
36    F64,
37    F128,
38}
39
40#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
41pub enum BuiltinType {
42    Char,
43    Bool,
44    Str,
45    Int(BuiltinInt),
46    Uint(BuiltinUint),
47    Float(BuiltinFloat),
48}
49
50impl BuiltinType {
51    #[rustfmt::skip]
52    pub fn all_builtin_types() -> [(Name, BuiltinType); 19] {
53        [
54            (Name::new_symbol_root(sym::char), BuiltinType::Char),
55            (Name::new_symbol_root(sym::bool), BuiltinType::Bool),
56            (Name::new_symbol_root(sym::str),  BuiltinType::Str),
57
58            (Name::new_symbol_root(sym::isize), BuiltinType::Int(BuiltinInt::Isize)),
59            (Name::new_symbol_root(sym::i8),    BuiltinType::Int(BuiltinInt::I8)),
60            (Name::new_symbol_root(sym::i16),   BuiltinType::Int(BuiltinInt::I16)),
61            (Name::new_symbol_root(sym::i32),   BuiltinType::Int(BuiltinInt::I32)),
62            (Name::new_symbol_root(sym::i64),   BuiltinType::Int(BuiltinInt::I64)),
63            (Name::new_symbol_root(sym::i128),  BuiltinType::Int(BuiltinInt::I128)),
64
65            (Name::new_symbol_root(sym::usize), BuiltinType::Uint(BuiltinUint::Usize)),
66            (Name::new_symbol_root(sym::u8),    BuiltinType::Uint(BuiltinUint::U8)),
67            (Name::new_symbol_root(sym::u16),   BuiltinType::Uint(BuiltinUint::U16)),
68            (Name::new_symbol_root(sym::u32),   BuiltinType::Uint(BuiltinUint::U32)),
69            (Name::new_symbol_root(sym::u64),   BuiltinType::Uint(BuiltinUint::U64)),
70            (Name::new_symbol_root(sym::u128),  BuiltinType::Uint(BuiltinUint::U128)),
71
72            (Name::new_symbol_root(sym::f16), BuiltinType::Float(BuiltinFloat::F16)),
73            (Name::new_symbol_root(sym::f32), BuiltinType::Float(BuiltinFloat::F32)),
74            (Name::new_symbol_root(sym::f64), BuiltinType::Float(BuiltinFloat::F64)),
75            (Name::new_symbol_root(sym::f128), BuiltinType::Float(BuiltinFloat::F128)),
76        ]
77    }
78
79    pub fn by_name(name: &Name) -> Option<Self> {
80        Self::all_builtin_types()
81            .iter()
82            .find_map(|(n, ty)| if n == name { Some(*ty) } else { None })
83    }
84}
85
86impl AsName for BuiltinType {
87    fn as_name(&self) -> Name {
88        match self {
89            BuiltinType::Char => Name::new_symbol_root(sym::char),
90            BuiltinType::Bool => Name::new_symbol_root(sym::bool),
91            BuiltinType::Str => Name::new_symbol_root(sym::str),
92            BuiltinType::Int(it) => match it {
93                BuiltinInt::Isize => Name::new_symbol_root(sym::isize),
94                BuiltinInt::I8 => Name::new_symbol_root(sym::i8),
95                BuiltinInt::I16 => Name::new_symbol_root(sym::i16),
96                BuiltinInt::I32 => Name::new_symbol_root(sym::i32),
97                BuiltinInt::I64 => Name::new_symbol_root(sym::i64),
98                BuiltinInt::I128 => Name::new_symbol_root(sym::i128),
99            },
100            BuiltinType::Uint(it) => match it {
101                BuiltinUint::Usize => Name::new_symbol_root(sym::usize),
102                BuiltinUint::U8 => Name::new_symbol_root(sym::u8),
103                BuiltinUint::U16 => Name::new_symbol_root(sym::u16),
104                BuiltinUint::U32 => Name::new_symbol_root(sym::u32),
105                BuiltinUint::U64 => Name::new_symbol_root(sym::u64),
106                BuiltinUint::U128 => Name::new_symbol_root(sym::u128),
107            },
108            BuiltinType::Float(it) => match it {
109                BuiltinFloat::F16 => Name::new_symbol_root(sym::f16),
110                BuiltinFloat::F32 => Name::new_symbol_root(sym::f32),
111                BuiltinFloat::F64 => Name::new_symbol_root(sym::f64),
112                BuiltinFloat::F128 => Name::new_symbol_root(sym::f128),
113            },
114        }
115    }
116}
117
118impl fmt::Display for BuiltinType {
119    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
120        match self {
121            BuiltinType::Char => f.write_str("char"),
122            BuiltinType::Bool => f.write_str("bool"),
123            BuiltinType::Str => f.write_str("str"),
124            BuiltinType::Int(it) => it.fmt(f),
125            BuiltinType::Uint(it) => it.fmt(f),
126            BuiltinType::Float(it) => it.fmt(f),
127        }
128    }
129}
130
131#[rustfmt::skip]
132impl BuiltinInt {
133    pub fn from_suffix(suffix: &str) -> Option<BuiltinInt> {
134        let res = match suffix {
135            "isize" => Self::Isize,
136            "i8"    => Self::I8,
137            "i16"   => Self::I16,
138            "i32"   => Self::I32,
139            "i64"   => Self::I64,
140            "i128"  => Self::I128,
141
142            _ => return None,
143        };
144        Some(res)
145    }
146    pub fn from_suffix_sym(suffix: &Symbol) -> Option<BuiltinInt> {
147        let res = match suffix {
148            s if *s == sym::isize => Self::Isize,
149            s if *s == sym::i8    => Self::I8,
150            s if *s == sym::i16   => Self::I16,
151            s if *s == sym::i32   => Self::I32,
152            s if *s == sym::i64   => Self::I64,
153            s if *s == sym::i128  => Self::I128,
154            _ => return None,
155        };
156        Some(res)
157    }
158}
159
160#[rustfmt::skip]
161impl BuiltinUint {
162    pub fn from_suffix(suffix: &str) -> Option<BuiltinUint> {
163        let res = match suffix {
164            "usize" => Self::Usize,
165            "u8"    => Self::U8,
166            "u16"   => Self::U16,
167            "u32"   => Self::U32,
168            "u64"   => Self::U64,
169            "u128"  => Self::U128,
170
171            _ => return None,
172        };
173        Some(res)
174    }
175    pub fn from_suffix_sym(suffix: &Symbol) -> Option<BuiltinUint> {
176        let res = match suffix {
177            s if *s == sym::usize => Self::Usize,
178            s if *s == sym::u8    => Self::U8,
179            s if *s == sym::u16   => Self::U16,
180            s if *s == sym::u32   => Self::U32,
181            s if *s == sym::u64   => Self::U64,
182            s if *s == sym::u128  => Self::U128,
183
184            _ => return None,
185        };
186        Some(res)
187    }
188}
189
190#[rustfmt::skip]
191impl BuiltinFloat {
192    pub fn from_suffix(suffix: &str) -> Option<BuiltinFloat> {
193        let res = match suffix {
194            "f16" => BuiltinFloat::F16,
195            "f32" => BuiltinFloat::F32,
196            "f64" => BuiltinFloat::F64,
197            "f128" => BuiltinFloat::F128,
198            _ => return None,
199        };
200        Some(res)
201    }
202}
203
204impl fmt::Display for BuiltinInt {
205    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
206        f.write_str(match self {
207            BuiltinInt::Isize => "isize",
208            BuiltinInt::I8 => "i8",
209            BuiltinInt::I16 => "i16",
210            BuiltinInt::I32 => "i32",
211            BuiltinInt::I64 => "i64",
212            BuiltinInt::I128 => "i128",
213        })
214    }
215}
216
217impl fmt::Display for BuiltinUint {
218    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
219        f.write_str(match self {
220            BuiltinUint::Usize => "usize",
221            BuiltinUint::U8 => "u8",
222            BuiltinUint::U16 => "u16",
223            BuiltinUint::U32 => "u32",
224            BuiltinUint::U64 => "u64",
225            BuiltinUint::U128 => "u128",
226        })
227    }
228}
229
230impl fmt::Display for BuiltinFloat {
231    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
232        f.write_str(match self {
233            BuiltinFloat::F16 => "f16",
234            BuiltinFloat::F32 => "f32",
235            BuiltinFloat::F64 => "f64",
236            BuiltinFloat::F128 => "f128",
237        })
238    }
239}