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