]> git.lizzy.rs Git - rust.git/blob - crates/hir_def/src/builtin_type.rs
Merge #6924
[rust.git] / crates / hir_def / src / 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
6 use std::fmt;
7
8 use hir_expand::name::{name, AsName, Name};
9
10 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
11 pub enum Signedness {
12     Signed,
13     Unsigned,
14 }
15
16 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
17 pub enum IntBitness {
18     Xsize,
19     X8,
20     X16,
21     X32,
22     X64,
23     X128,
24 }
25
26 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
27 pub enum FloatBitness {
28     X32,
29     X64,
30 }
31
32 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
33 pub struct BuiltinInt {
34     pub signedness: Signedness,
35     pub bitness: IntBitness,
36 }
37
38 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
39 pub struct BuiltinFloat {
40     pub bitness: FloatBitness,
41 }
42
43 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
44 pub enum BuiltinType {
45     Char,
46     Bool,
47     Str,
48     Int(BuiltinInt),
49     Float(BuiltinFloat),
50 }
51
52 impl BuiltinType {
53     #[rustfmt::skip]
54     pub const ALL: &'static [(Name, BuiltinType)] = &[
55         (name![char], BuiltinType::Char),
56         (name![bool], BuiltinType::Bool),
57         (name![str],  BuiltinType::Str),
58
59         (name![isize], BuiltinType::Int(BuiltinInt::ISIZE)),
60         (name![i8],    BuiltinType::Int(BuiltinInt::I8)),
61         (name![i16],   BuiltinType::Int(BuiltinInt::I16)),
62         (name![i32],   BuiltinType::Int(BuiltinInt::I32)),
63         (name![i64],   BuiltinType::Int(BuiltinInt::I64)),
64         (name![i128],  BuiltinType::Int(BuiltinInt::I128)),
65
66         (name![usize], BuiltinType::Int(BuiltinInt::USIZE)),
67         (name![u8],    BuiltinType::Int(BuiltinInt::U8)),
68         (name![u16],   BuiltinType::Int(BuiltinInt::U16)),
69         (name![u32],   BuiltinType::Int(BuiltinInt::U32)),
70         (name![u64],   BuiltinType::Int(BuiltinInt::U64)),
71         (name![u128],  BuiltinType::Int(BuiltinInt::U128)),
72
73         (name![f32], BuiltinType::Float(BuiltinFloat::F32)),
74         (name![f64], BuiltinType::Float(BuiltinFloat::F64)),
75     ];
76 }
77
78 impl AsName for BuiltinType {
79     fn as_name(&self) -> Name {
80         match self {
81             BuiltinType::Char => name![char],
82             BuiltinType::Bool => name![bool],
83             BuiltinType::Str => name![str],
84             BuiltinType::Int(BuiltinInt { signedness, bitness }) => match (signedness, bitness) {
85                 (Signedness::Signed, IntBitness::Xsize) => name![isize],
86                 (Signedness::Signed, IntBitness::X8) => name![i8],
87                 (Signedness::Signed, IntBitness::X16) => name![i16],
88                 (Signedness::Signed, IntBitness::X32) => name![i32],
89                 (Signedness::Signed, IntBitness::X64) => name![i64],
90                 (Signedness::Signed, IntBitness::X128) => name![i128],
91
92                 (Signedness::Unsigned, IntBitness::Xsize) => name![usize],
93                 (Signedness::Unsigned, IntBitness::X8) => name![u8],
94                 (Signedness::Unsigned, IntBitness::X16) => name![u16],
95                 (Signedness::Unsigned, IntBitness::X32) => name![u32],
96                 (Signedness::Unsigned, IntBitness::X64) => name![u64],
97                 (Signedness::Unsigned, IntBitness::X128) => name![u128],
98             },
99             BuiltinType::Float(BuiltinFloat { bitness }) => match bitness {
100                 FloatBitness::X32 => name![f32],
101                 FloatBitness::X64 => name![f64],
102             },
103         }
104     }
105 }
106
107 impl fmt::Display for BuiltinType {
108     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109         let type_name = self.as_name();
110         type_name.fmt(f)
111     }
112 }
113
114 #[rustfmt::skip]
115 impl BuiltinInt {
116     pub const ISIZE: BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::Xsize   };
117     pub const I8   : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X8      };
118     pub const I16  : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X16     };
119     pub const I32  : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X32     };
120     pub const I64  : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X64     };
121     pub const I128 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X128    };
122
123     pub const USIZE: BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::Xsize };
124     pub const U8   : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X8    };
125     pub const U16  : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X16   };
126     pub const U32  : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X32   };
127     pub const U64  : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X64   };
128     pub const U128 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X128  };
129
130
131     pub fn from_suffix(suffix: &str) -> Option<BuiltinInt> {
132         let res = match suffix {
133             "isize" => Self::ISIZE,
134             "i8"    => Self::I8,
135             "i16"   => Self::I16,
136             "i32"   => Self::I32,
137             "i64"   => Self::I64,
138             "i128"  => Self::I128,
139
140             "usize" => Self::USIZE,
141             "u8"    => Self::U8,
142             "u16"   => Self::U16,
143             "u32"   => Self::U32,
144             "u64"   => Self::U64,
145             "u128"  => Self::U128,
146
147             _ => return None,
148         };
149         Some(res)
150     }
151 }
152
153 #[rustfmt::skip]
154 impl BuiltinFloat {
155     pub const F32: BuiltinFloat = BuiltinFloat { bitness: FloatBitness::X32 };
156     pub const F64: BuiltinFloat = BuiltinFloat { bitness: FloatBitness::X64 };
157
158     pub fn from_suffix(suffix: &str) -> Option<BuiltinFloat> {
159         let res = match suffix {
160             "f32" => BuiltinFloat::F32,
161             "f64" => BuiltinFloat::F64,
162             _ => return None,
163         };
164         Some(res)
165     }
166 }