Skip to main content

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