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    /// FIXME(#146922): add all the common types
79    Other,
80}
81
82/// Compile-time type information about tuples.
83#[derive(Debug)]
84#[non_exhaustive]
85#[unstable(feature = "type_info", issue = "146922")]
86pub struct Tuple {
87    /// All fields of a tuple.
88    pub fields: &'static [Field],
89}
90
91/// Compile-time type information about fields of tuples, structs and enum variants.
92#[derive(Debug)]
93#[non_exhaustive]
94#[unstable(feature = "type_info", issue = "146922")]
95pub struct Field {
96    /// The name of the field.
97    pub name: &'static str,
98    /// The field's type.
99    pub ty: TypeId,
100    /// Offset in bytes from the parent type
101    pub offset: usize,
102}
103
104/// Compile-time type information about arrays.
105#[derive(Debug)]
106#[non_exhaustive]
107#[unstable(feature = "type_info", issue = "146922")]
108pub struct Array {
109    /// The type of each element in the array.
110    pub element_ty: TypeId,
111    /// The length of the array.
112    pub len: usize,
113}
114
115/// Compile-time type information about slices.
116#[derive(Debug)]
117#[non_exhaustive]
118#[unstable(feature = "type_info", issue = "146922")]
119pub struct Slice {
120    /// The type of each element in the slice.
121    pub element_ty: TypeId,
122}
123
124/// Compile-time type information about dynamic traits.
125/// FIXME(#146922): Add super traits and generics
126#[derive(Debug)]
127#[non_exhaustive]
128#[unstable(feature = "type_info", issue = "146922")]
129pub struct DynTrait {
130    /// The predicates of  a dynamic trait.
131    pub predicates: &'static [DynTraitPredicate],
132}
133
134/// Compile-time type information about a dynamic trait predicate.
135#[derive(Debug)]
136#[non_exhaustive]
137#[unstable(feature = "type_info", issue = "146922")]
138pub struct DynTraitPredicate {
139    /// The type of the trait as a dynamic trait type.
140    pub trait_ty: Trait,
141}
142
143/// Compile-time type information about a trait.
144#[derive(Debug)]
145#[non_exhaustive]
146#[unstable(feature = "type_info", issue = "146922")]
147pub struct Trait {
148    /// The TypeId of the trait as a dynamic type
149    pub ty: TypeId,
150    /// Whether the trait is an auto trait
151    pub is_auto: bool,
152}
153
154/// Compile-time type information about arrays.
155#[derive(Debug)]
156#[non_exhaustive]
157#[unstable(feature = "type_info", issue = "146922")]
158pub struct Struct {
159    /// Instantiated generics of the struct.
160    pub generics: &'static [Generic],
161    /// All fields of the struct.
162    pub fields: &'static [Field],
163    /// Whether the struct field list is non-exhaustive.
164    pub non_exhaustive: bool,
165}
166
167/// Compile-time type information about unions.
168#[derive(Debug)]
169#[non_exhaustive]
170#[unstable(feature = "type_info", issue = "146922")]
171pub struct Union {
172    /// Instantiated generics of the union.
173    pub generics: &'static [Generic],
174    /// All fields of the union.
175    pub fields: &'static [Field],
176}
177
178/// Compile-time type information about enums.
179#[derive(Debug)]
180#[non_exhaustive]
181#[unstable(feature = "type_info", issue = "146922")]
182pub struct Enum {
183    /// Instantiated generics of the enum.
184    pub generics: &'static [Generic],
185    /// All variants of the enum.
186    pub variants: &'static [Variant],
187    /// Whether the enum variant list is non-exhaustive.
188    pub non_exhaustive: bool,
189}
190
191/// Compile-time type information about variants of enums.
192#[derive(Debug)]
193#[non_exhaustive]
194#[unstable(feature = "type_info", issue = "146922")]
195pub struct Variant {
196    /// The name of the variant.
197    pub name: &'static str,
198    /// All fields of the variant.
199    pub fields: &'static [Field],
200    /// Whether the enum variant fields is non-exhaustive.
201    pub non_exhaustive: bool,
202}
203
204/// Compile-time type information about instantiated generics of structs, enum and union variants.
205#[derive(Debug)]
206#[non_exhaustive]
207#[unstable(feature = "type_info", issue = "146922")]
208pub enum Generic {
209    /// Lifetimes.
210    Lifetime(Lifetime),
211    /// Types.
212    Type(GenericType),
213    /// Const parameters.
214    Const(Const),
215}
216
217/// Compile-time type information about generic lifetimes.
218#[derive(Debug)]
219#[non_exhaustive]
220#[unstable(feature = "type_info", issue = "146922")]
221pub struct Lifetime {
222    // No additional information to provide for now.
223}
224
225/// Compile-time type information about instantiated generic types.
226#[derive(Debug)]
227#[non_exhaustive]
228#[unstable(feature = "type_info", issue = "146922")]
229pub struct GenericType {
230    /// The type itself.
231    pub ty: TypeId,
232}
233
234/// Compile-time type information about generic const parameters.
235#[derive(Debug)]
236#[non_exhaustive]
237#[unstable(feature = "type_info", issue = "146922")]
238pub struct Const {
239    /// The const's type.
240    pub ty: TypeId,
241}
242
243/// Compile-time type information about `bool`.
244#[derive(Debug)]
245#[non_exhaustive]
246#[unstable(feature = "type_info", issue = "146922")]
247pub struct Bool {
248    // No additional information to provide for now.
249}
250
251/// Compile-time type information about `char`.
252#[derive(Debug)]
253#[non_exhaustive]
254#[unstable(feature = "type_info", issue = "146922")]
255pub struct Char {
256    // No additional information to provide for now.
257}
258
259/// Compile-time type information about signed and unsigned integer types.
260#[derive(Debug)]
261#[non_exhaustive]
262#[unstable(feature = "type_info", issue = "146922")]
263pub struct Int {
264    /// The bit width of the signed integer type.
265    pub bits: u32,
266    /// Whether the integer type is signed.
267    pub signed: bool,
268}
269
270/// Compile-time type information about floating-point types.
271#[derive(Debug)]
272#[non_exhaustive]
273#[unstable(feature = "type_info", issue = "146922")]
274pub struct Float {
275    /// The bit width of the floating-point type.
276    pub bits: u32,
277}
278
279/// Compile-time type information about string slice types.
280#[derive(Debug)]
281#[non_exhaustive]
282#[unstable(feature = "type_info", issue = "146922")]
283pub struct Str {
284    // No additional information to provide for now.
285}
286
287/// Compile-time type information about references.
288#[derive(Debug)]
289#[non_exhaustive]
290#[unstable(feature = "type_info", issue = "146922")]
291pub struct Reference {
292    /// The type of the value being referred to.
293    pub pointee: TypeId,
294    /// Whether this reference is mutable or not.
295    pub mutable: bool,
296}
297
298/// Compile-time type information about pointers.
299#[derive(Debug)]
300#[non_exhaustive]
301#[unstable(feature = "type_info", issue = "146922")]
302pub struct Pointer {
303    /// The type of the value being pointed to.
304    pub pointee: TypeId,
305    /// Whether this pointer is mutable or not.
306    pub mutable: bool,
307}