core/intrinsics/reflection.rs
1//! Intrinsics for compile time reflection
2//!
3//! This are all methods operating on [`TypeId`](core::any::TypeId) which is the
4//! entry point to all compile time reflection.
5
6use crate::ptr;
7
8/// Gets an identifier which is globally unique to the specified type. This
9/// function will return the same value for a type regardless of whichever
10/// crate it is invoked in.
11///
12/// Note that, unlike most intrinsics, this can only be called at compile-time
13/// as backends do not have an implementation for it. The only caller (its
14/// stable counterpart) wraps this intrinsic call in a `const` block so that
15/// backends only see an evaluated constant.
16///
17/// The stabilized version of this intrinsic is [`core::any::TypeId::of`].
18#[rustc_nounwind]
19#[unstable(feature = "core_intrinsics", issue = "none")]
20#[rustc_intrinsic]
21#[rustc_comptime]
22pub fn type_id<T: ?Sized>() -> crate::any::TypeId;
23
24/// Compute the type information of a concrete type.
25/// It can only be called at compile time, the backends do
26/// not implement it.
27#[rustc_intrinsic]
28#[unstable(feature = "core_intrinsics", issue = "none")]
29#[rustc_comptime]
30pub fn type_id_type_of(_id: crate::any::TypeId) -> crate::mem::type_info::Type;
31
32/// Tests (at compile-time) if two [`crate::any::TypeId`] instances identify the
33/// same type. This is necessary because at const-eval time the actual discriminating
34/// data is opaque and cannot be inspected directly.
35///
36/// The stabilized version of this intrinsic is the [PartialEq] impl for [`core::any::TypeId`].
37#[rustc_nounwind]
38#[unstable(feature = "core_intrinsics", issue = "none")]
39#[rustc_intrinsic]
40#[rustc_do_not_const_check]
41pub const fn type_id_eq(a: crate::any::TypeId, b: crate::any::TypeId) -> bool {
42 // SAFETY: we know `TypeId` is 16 bytes of initialized data.
43 // This is runtime-only code so we do not have to worry about provenance.
44 unsafe { crate::mem::transmute::<_, u128>(a) == crate::mem::transmute::<_, u128>(b) }
45}
46
47#[rustc_intrinsic]
48#[rustc_comptime]
49#[unstable(feature = "core_intrinsics", issue = "none")]
50/// Check if a type represented by a `TypeId` implements a trait represented by a `TypeId`.
51/// It can only be called at compile time, the backends do
52/// not implement it. If it implements the trait the dyn metadata gets returned for vtable access.
53pub fn type_id_vtable(
54 _id: crate::any::TypeId,
55 _trait: crate::any::TypeId,
56) -> Option<ptr::DynMetadata<*const ()>>;
57
58/// Gets a static string slice containing the name of a type.
59///
60/// Note that, unlike most intrinsics, this can only be called at compile-time
61/// as backends do not have an implementation for it. The only caller (its
62/// stable counterpart) wraps this intrinsic call in a `const` block so that
63/// backends only see an evaluated constant.
64///
65/// The stabilized version of this intrinsic is [`core::any::type_name`].
66#[rustc_nounwind]
67#[unstable(feature = "core_intrinsics", issue = "none")]
68#[rustc_intrinsic]
69#[rustc_comptime]
70pub fn type_name<T: ?Sized>() -> &'static str;
71
72/// Returns whether the type represented by this `TypeId` is a signed integer.
73///
74/// The more user-friendly version of this intrinsic is [`core::any::TypeId::is_signed`].
75#[rustc_intrinsic]
76#[unstable(feature = "core_intrinsics", issue = "none")]
77#[rustc_comptime]
78pub fn type_id_is_signed(_id: crate::any::TypeId) -> bool;
79
80/// Gets the length of the array represented by this `TypeId`.
81///
82/// The more user-friendly version of this intrinsic is [`core::any::TypeId::array_len`].
83#[rustc_intrinsic]
84#[unstable(feature = "core_intrinsics", issue = "none")]
85#[rustc_comptime]
86pub fn type_id_array_len(_id: crate::any::TypeId) -> usize;
87
88/// Gets the type of each element of the array or slice represented by this `TypeId`.
89///
90/// The more user-friendly version of this intrinsic is [`core::any::TypeId::element_ty`].
91#[rustc_intrinsic]
92#[unstable(feature = "core_intrinsics", issue = "none")]
93#[rustc_comptime]
94pub fn type_id_element_ty(_id: crate::any::TypeId) -> Option<crate::any::TypeId>;
95
96/// Gets the size of the type represented by this `TypeId`.
97///
98/// The more user-friendly version of this intrinsic is [`core::any::TypeId::size`].
99#[rustc_intrinsic]
100#[unstable(feature = "core_intrinsics", issue = "none")]
101#[rustc_comptime]
102pub fn type_id_size_of(_id: crate::any::TypeId) -> Option<usize>;
103
104/// Gets the number of variants of the type represented by this `TypeId`.
105///
106/// The more user-friendly version of this intrinsic is [`core::any::TypeId::variants`].
107#[rustc_intrinsic]
108#[unstable(feature = "core_intrinsics", issue = "none")]
109#[rustc_comptime]
110pub fn type_id_variants(_id: crate::any::TypeId) -> usize;
111
112/// Gets the name of the variant represented by the base `TypeId` and variant_idx.
113///
114/// The more user-friendly version of this intrinsic is [`core::mem::type_info::VariantId::name`].
115///
116/// [`TypeId`]: crate::any::TypeId
117#[rustc_intrinsic]
118#[unstable(feature = "core_intrinsics", issue = "none")]
119#[rustc_comptime]
120pub fn type_id_variant_name(_base: crate::any::TypeId, _variant_index: usize) -> &'static str;
121
122/// Returns true when the variant represented by the base `TypeId` and variant_idx is non
123/// exhaustive.
124///
125/// The more user-friendly version of this intrinsic is
126/// [`core::mem::type_info::VariantId::non_exhaustive`].
127///
128/// [`TypeId`]: crate::any::TypeId
129#[rustc_intrinsic]
130#[unstable(feature = "core_intrinsics", issue = "none")]
131#[rustc_comptime]
132pub fn type_id_variant_non_exhaustive(base: crate::any::TypeId, variant: usize) -> bool;
133
134/// Gets the number of fields at the given `variant_index` represented by this `TypeId`.
135///
136/// The more user-friendly version of this intrinsic is [`core::any::TypeId::fields`].
137#[rustc_intrinsic]
138#[unstable(feature = "core_intrinsics", issue = "none")]
139#[rustc_comptime]
140pub fn type_id_fields(_id: crate::any::TypeId, _variant_index: usize) -> usize;
141
142/// Checks whether this type is non-exhaustive.
143#[rustc_intrinsic]
144#[unstable(feature = "core_intrinsics", issue = "none")]
145#[rustc_comptime]
146pub fn type_id_non_exhaustive(_id: crate::any::TypeId) -> bool;
147
148/// Returns the list of generic args on this type.
149/// Only meaningful for Adts, closures, ... Everything else returns an empty slice.
150#[rustc_intrinsic]
151#[unstable(feature = "core_intrinsics", issue = "none")]
152#[rustc_comptime]
153pub fn type_id_generics(_id: crate::any::TypeId) -> &'static [crate::mem::type_info::Generic];
154
155/// Gets the [`FieldRepresentingType`]'s `TypeId` at the given index of the type represented by this `TypeId`.
156///
157/// The more user-friendly version of this intrinsic is [`core::any::TypeId::field`].
158///
159/// [`FieldRepresentingType`]: crate::field::FieldRepresentingType
160#[rustc_intrinsic]
161#[unstable(feature = "core_intrinsics", issue = "none")]
162#[rustc_comptime]
163pub fn type_id_field_representing_type(
164 _id: crate::any::TypeId,
165 _variant_index: usize,
166 _field_index: usize,
167) -> crate::any::TypeId;
168
169/// Given a `TypeId` that represents a pointer this returns the `TypeId` which that pointer
170/// points to. When called on anything else this returns None.
171///
172/// The more user-friendly version of this intrinsic is [`core::any::TypeId::points_to`].
173#[rustc_intrinsic]
174#[unstable(feature = "core_intrinsics", issue = "none")]
175#[rustc_comptime]
176pub fn type_id_points_to(_id: crate::any::TypeId) -> Option<crate::any::TypeId>;
177
178/// Given a `TypeId` that represents a pointer returns whether that pointer is mutable.
179/// When called on anything else this returns `false`.
180///
181/// The more user-friendly version of this intrinsic is [`core::any::TypeId::points_mutably`].
182#[rustc_intrinsic]
183#[unstable(feature = "core_intrinsics", issue = "none")]
184#[rustc_comptime]
185pub fn type_id_points_mutably(_id: crate::any::TypeId) -> bool;
186
187/// Given a `TypeId` that represents a function pointer returns an [`core::mem::type_info::FnPtr`].
188/// When called on something else this returns `None`.
189///
190/// The more user-friendly version of this intrinsic is [`core::any::TypeId::function_ptr`].
191#[rustc_intrinsic]
192#[unstable(feature = "core_intrinsics", issue = "none")]
193#[rustc_comptime]
194pub fn type_id_function_ptr(_type_id: crate::any::TypeId) -> Option<crate::mem::type_info::FnPtr>;