Skip to main content

core/mem/
type_info.rs

1//! MVP for exposing compile-time information about types in a
2//! runtime or const-eval processable way.
3
4use crate::any::TypeId;
5use crate::intrinsics::{type_id, type_of};
6
7/// Compile-time type information.
8#[derive(Debug)]
9#[non_exhaustive]
10#[lang = "type_info"]
11#[unstable(feature = "type_info", issue = "146922")]
12pub struct Type {
13    /// Per-type information
14    pub kind: TypeKind,
15    /// Size of the type. `None` if it is unsized
16    pub size: Option<usize>,
17}
18
19impl TypeId {
20    /// Compute the type information of a concrete type.
21    /// It can only be called at compile time.
22    #[unstable(feature = "type_info", issue = "146922")]
23    #[rustc_const_unstable(feature = "type_info", issue = "146922")]
24    pub const fn info(self) -> Type {
25        type_of(self)
26    }
27}
28
29impl Type {
30    /// Returns the type information of the generic type parameter.
31    ///
32    /// Note: Unlike `TypeId`s obtained via `TypeId::of`, the `Type`
33    /// struct and its fields contain `TypeId`s that are not necessarily
34    /// derived from types that outlive `'static`. This means that using
35    /// the `TypeId`s (transitively) obtained from this function will
36    /// be able to break invariants that other `TypeId` consuming crates
37    /// may have assumed to hold.
38    #[unstable(feature = "type_info", issue = "146922")]
39    #[rustc_const_unstable(feature = "type_info", issue = "146922")]
40    pub const fn of<T: ?Sized>() -> Self {
41        const { type_id::<T>().info() }
42    }
43}
44
45/// Compile-time type information.
46#[derive(Debug)]
47#[non_exhaustive]
48#[unstable(feature = "type_info", issue = "146922")]
49pub enum TypeKind {
50    /// Tuples.
51    Tuple(Tuple),
52    /// Arrays.
53    Array(Array),
54    /// Slices.
55    Slice(Slice),
56    /// Dynamic Traits.
57    DynTrait(DynTrait),
58    /// Structs.
59    Struct(Struct),
60    /// Enums.
61    Enum(Enum),
62    /// Unions.
63    Union(Union),
64    /// Primitive boolean type.
65    Bool(Bool),
66    /// Primitive character type.
67    Char(Char),
68    /// Primitive signed and unsigned integer type.
69    Int(Int),
70    /// Primitive floating-point type.
71    Float(Float),
72    /// String slice type.
73    Str(Str),
74    /// References.
75    Reference(Reference),
76    /// Pointers.
77    Pointer(Pointer),
78    /// Function pointers.
79    FnPtr(FnPtr),
80    /// FIXME(#146922): add all the common types
81    Other,
82}
83
84/// Compile-time type information about tuples.
85#[derive(Debug)]
86#[non_exhaustive]
87#[unstable(feature = "type_info", issue = "146922")]
88pub struct Tuple {
89    /// All fields of a tuple.
90    pub fields: &'static [Field],
91}
92
93/// Compile-time type information about fields of tuples, structs and enum variants.
94#[derive(Debug)]
95#[non_exhaustive]
96#[unstable(feature = "type_info", issue = "146922")]
97pub struct Field {
98    /// The name of the field.
99    pub name: &'static str,
100    /// The field's type.
101    pub ty: TypeId,
102    /// Offset in bytes from the parent type
103    pub offset: usize,
104}
105
106/// Compile-time type information about arrays.
107#[derive(Debug)]
108#[non_exhaustive]
109#[unstable(feature = "type_info", issue = "146922")]
110pub struct Array {
111    /// The type of each element in the array.
112    pub element_ty: TypeId,
113    /// The length of the array.
114    pub len: usize,
115}
116
117/// Compile-time type information about slices.
118#[derive(Debug)]
119#[non_exhaustive]
120#[unstable(feature = "type_info", issue = "146922")]
121pub struct Slice {
122    /// The type of each element in the slice.
123    pub element_ty: TypeId,
124}
125
126/// Compile-time type information about dynamic traits.
127/// FIXME(#146922): Add super traits and generics
128#[derive(Debug)]
129#[non_exhaustive]
130#[unstable(feature = "type_info", issue = "146922")]
131pub struct DynTrait {
132    /// The predicates of  a dynamic trait.
133    pub predicates: &'static [DynTraitPredicate],
134}
135
136/// Compile-time type information about a dynamic trait predicate.
137#[derive(Debug)]
138#[non_exhaustive]
139#[unstable(feature = "type_info", issue = "146922")]
140pub struct DynTraitPredicate {
141    /// The type of the trait as a dynamic trait type.
142    pub trait_ty: Trait,
143}
144
145/// Compile-time type information about a trait.
146#[derive(Debug)]
147#[non_exhaustive]
148#[unstable(feature = "type_info", issue = "146922")]
149pub struct Trait {
150    /// The TypeId of the trait as a dynamic type
151    pub ty: TypeId,
152    /// Whether the trait is an auto trait
153    pub is_auto: bool,
154}
155
156/// Compile-time type information about structs.
157#[derive(Debug)]
158#[non_exhaustive]
159#[unstable(feature = "type_info", issue = "146922")]
160pub struct Struct {
161    /// Instantiated generics of the struct.
162    pub generics: &'static [Generic],
163    /// All fields of the struct.
164    pub fields: &'static [Field],
165    /// Whether the struct field list is non-exhaustive.
166    pub non_exhaustive: bool,
167}
168
169/// Compile-time type information about unions.
170#[derive(Debug)]
171#[non_exhaustive]
172#[unstable(feature = "type_info", issue = "146922")]
173pub struct Union {
174    /// Instantiated generics of the union.
175    pub generics: &'static [Generic],
176    /// All fields of the union.
177    pub fields: &'static [Field],
178}
179
180/// Compile-time type information about enums.
181#[derive(Debug)]
182#[non_exhaustive]
183#[unstable(feature = "type_info", issue = "146922")]
184pub struct Enum {
185    /// Instantiated generics of the enum.
186    pub generics: &'static [Generic],
187    /// All variants of the enum.
188    pub variants: &'static [Variant],
189    /// Whether the enum variant list is non-exhaustive.
190    pub non_exhaustive: bool,
191}
192
193/// Compile-time type information about variants of enums.
194#[derive(Debug)]
195#[non_exhaustive]
196#[unstable(feature = "type_info", issue = "146922")]
197pub struct Variant {
198    /// The name of the variant.
199    pub name: &'static str,
200    /// All fields of the variant.
201    pub fields: &'static [Field],
202    /// Whether the enum variant fields is non-exhaustive.
203    pub non_exhaustive: bool,
204}
205
206/// Compile-time type information about instantiated generics of structs, enum and union variants.
207#[derive(Debug)]
208#[non_exhaustive]
209#[unstable(feature = "type_info", issue = "146922")]
210pub enum Generic {
211    /// Lifetimes.
212    Lifetime(Lifetime),
213    /// Types.
214    Type(GenericType),
215    /// Const parameters.
216    Const(Const),
217}
218
219/// Compile-time type information about generic lifetimes.
220#[derive(Debug)]
221#[non_exhaustive]
222#[unstable(feature = "type_info", issue = "146922")]
223pub struct Lifetime {
224    // No additional information to provide for now.
225}
226
227/// Compile-time type information about instantiated generic types.
228#[derive(Debug)]
229#[non_exhaustive]
230#[unstable(feature = "type_info", issue = "146922")]
231pub struct GenericType {
232    /// The type itself.
233    pub ty: TypeId,
234}
235
236/// Compile-time type information about generic const parameters.
237#[derive(Debug)]
238#[non_exhaustive]
239#[unstable(feature = "type_info", issue = "146922")]
240pub struct Const {
241    /// The const's type.
242    pub ty: TypeId,
243}
244
245/// Compile-time type information about `bool`.
246#[derive(Debug)]
247#[non_exhaustive]
248#[unstable(feature = "type_info", issue = "146922")]
249pub struct Bool {
250    // No additional information to provide for now.
251}
252
253/// Compile-time type information about `char`.
254#[derive(Debug)]
255#[non_exhaustive]
256#[unstable(feature = "type_info", issue = "146922")]
257pub struct Char {
258    // No additional information to provide for now.
259}
260
261/// Compile-time type information about signed and unsigned integer types.
262#[derive(Debug)]
263#[non_exhaustive]
264#[unstable(feature = "type_info", issue = "146922")]
265pub struct Int {
266    /// The bit width of the signed integer type.
267    pub bits: u32,
268    /// Whether the integer type is signed.
269    pub signed: bool,
270}
271
272/// Compile-time type information about floating-point types.
273#[derive(Debug)]
274#[non_exhaustive]
275#[unstable(feature = "type_info", issue = "146922")]
276pub struct Float {
277    /// The bit width of the floating-point type.
278    pub bits: u32,
279}
280
281/// Compile-time type information about string slice types.
282#[derive(Debug)]
283#[non_exhaustive]
284#[unstable(feature = "type_info", issue = "146922")]
285pub struct Str {
286    // No additional information to provide for now.
287}
288
289/// Compile-time type information about references.
290#[derive(Debug)]
291#[non_exhaustive]
292#[unstable(feature = "type_info", issue = "146922")]
293pub struct Reference {
294    /// The type of the value being referred to.
295    pub pointee: TypeId,
296    /// Whether this reference is mutable or not.
297    pub mutable: bool,
298}
299
300/// Compile-time type information about pointers.
301#[derive(Debug)]
302#[non_exhaustive]
303#[unstable(feature = "type_info", issue = "146922")]
304pub struct Pointer {
305    /// The type of the value being pointed to.
306    pub pointee: TypeId,
307    /// Whether this pointer is mutable or not.
308    pub mutable: bool,
309}
310
311#[derive(Debug)]
312#[unstable(feature = "type_info", issue = "146922")]
313/// Function pointer, e.g. fn(u8),
314pub struct FnPtr {
315    /// Unsafety, true is unsafe
316    pub unsafety: bool,
317
318    /// Abi, e.g. extern "C"
319    pub abi: Abi,
320
321    /// Function inputs
322    pub inputs: &'static [TypeId],
323
324    /// Function return type, default is TypeId::of::<()>
325    pub output: TypeId,
326
327    /// Vardiadic function, e.g. extern "C" fn add(n: usize, mut args: ...);
328    pub variadic: bool,
329}
330
331#[derive(Debug, Default)]
332#[non_exhaustive]
333#[unstable(feature = "type_info", issue = "146922")]
334/// Abi of [FnPtr]
335pub enum Abi {
336    /// Named abi, e.g. extern "custom", "stdcall" etc.
337    Named(&'static str),
338
339    /// Default
340    #[default]
341    ExternRust,
342
343    /// C-calling convention
344    ExternC,
345}