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::fmt;
6use crate::intrinsics::{self, type_id, type_of};
7use crate::marker::PointeeSized;
8use crate::ptr::DynMetadata;
9
10/// Compile-time type information.
11#[derive(Debug)]
12#[non_exhaustive]
13#[lang = "type_info"]
14#[unstable(feature = "type_info", issue = "146922")]
15pub struct Type {
16 /// Per-type information
17 pub kind: TypeKind,
18}
19
20/// Info of a trait implementation, you can retrieve the vtable with [Self::get_vtable]
21#[derive(Debug, PartialEq, Eq)]
22#[unstable(feature = "type_info", issue = "146922")]
23pub struct TraitImpl<T: PointeeSized> {
24 pub(crate) vtable: DynMetadata<T>,
25}
26
27impl<T: PointeeSized> TraitImpl<T> {
28 /// Gets the raw vtable for type reflection mapping
29 pub const fn get_vtable(&self) -> DynMetadata<T> {
30 self.vtable
31 }
32}
33
34impl TypeId {
35 /// Compute the type information of a concrete type.
36 /// It can only be called at compile time.
37 #[unstable(feature = "type_info", issue = "146922")]
38 #[rustc_const_unstable(feature = "type_info", issue = "146922")]
39 #[rustc_comptime]
40 pub fn info(self) -> Type {
41 type_of(self)
42 }
43}
44
45impl Type {
46 /// Returns the type information of the generic type parameter.
47 ///
48 /// Note: Unlike `TypeId`s obtained via `TypeId::of`, the `Type`
49 /// struct and its fields contain `TypeId`s that are not necessarily
50 /// derived from types that outlive `'static`. This means that using
51 /// the `TypeId`s (transitively) obtained from this function will
52 /// be able to break invariants that other `TypeId` consuming crates
53 /// may have assumed to hold.
54 #[unstable(feature = "type_info", issue = "146922")]
55 #[rustc_const_unstable(feature = "type_info", issue = "146922")]
56 pub const fn of<T: ?Sized>() -> Self {
57 const { type_id::<T>().info() }
58 }
59}
60
61// FIXME(reflection): get rid of the static lifetime bound on TypeId and remove this function.
62/// Returns the [TypeId] of the generic type parameter.
63///
64/// This is identical to [TypeId::of] but without the static lifetime bound. It will be removed
65/// in the future.
66#[must_use]
67#[unstable(feature = "type_info", issue = "146922")]
68#[rustc_const_unstable(feature = "type_info", issue = "146922")]
69pub const fn of<T: ?Sized>() -> TypeId {
70 const { intrinsics::type_id::<T>() }
71}
72
73/// Compile-time type information.
74#[derive(Debug)]
75#[non_exhaustive]
76#[unstable(feature = "type_info", issue = "146922")]
77pub enum TypeKind {
78 /// Tuples.
79 Tuple,
80 /// Arrays.
81 Array(Array),
82 /// Slices.
83 Slice(Slice),
84 /// Dynamic Traits.
85 DynTrait(DynTrait),
86 /// Structs.
87 Struct,
88 /// Enums.
89 Enum,
90 /// Unions.
91 Union,
92 /// Primitive boolean type.
93 Bool,
94 /// Primitive character type.
95 Char,
96 /// Primitive signed and unsigned integer type.
97 Int,
98 /// Primitive floating-point type.
99 Float,
100 /// String slice type.
101 Str(Str),
102 /// References.
103 Reference(Reference),
104 /// Pointers.
105 Pointer(Pointer),
106 /// Function pointers.
107 FnPtr(FnPtr),
108 /// FIXME(#146922): add all the common types
109 Other,
110}
111
112/// Compile-time type information about arrays.
113#[derive(Debug)]
114#[non_exhaustive]
115#[unstable(feature = "type_info", issue = "146922")]
116pub struct Array {
117 /// The type of each element in the array.
118 pub element_ty: TypeId,
119 /// The length of the array.
120 pub len: usize,
121}
122
123/// Compile-time type information about slices.
124#[derive(Debug)]
125#[non_exhaustive]
126#[unstable(feature = "type_info", issue = "146922")]
127pub struct Slice {
128 /// The type of each element in the slice.
129 pub element_ty: TypeId,
130}
131
132/// Compile-time type information about dynamic traits.
133/// FIXME(#146922): Add super traits and generics
134#[derive(Debug)]
135#[non_exhaustive]
136#[unstable(feature = "type_info", issue = "146922")]
137pub struct DynTrait {
138 /// The predicates of a dynamic trait.
139 pub predicates: &'static [DynTraitPredicate],
140}
141
142/// Compile-time type information about a dynamic trait predicate.
143#[derive(Debug)]
144#[non_exhaustive]
145#[unstable(feature = "type_info", issue = "146922")]
146pub struct DynTraitPredicate {
147 /// The type of the trait as a dynamic trait type.
148 pub trait_ty: Trait,
149}
150
151/// Compile-time type information about a trait.
152#[derive(Debug)]
153#[non_exhaustive]
154#[unstable(feature = "type_info", issue = "146922")]
155pub struct Trait {
156 /// The TypeId of the trait as a dynamic type
157 pub ty: TypeId,
158 /// Whether the trait is an auto trait
159 pub is_auto: bool,
160}
161
162/// Compile-time type information about instantiated generics of structs, enum and union variants.
163#[derive(Debug)]
164#[non_exhaustive]
165#[unstable(feature = "type_info", issue = "146922")]
166#[lang = "type_info_generic"]
167pub enum Generic {
168 /// Lifetimes.
169 Lifetime(Lifetime),
170 /// Types.
171 Type(GenericType),
172 /// Const parameters.
173 Const(Const),
174}
175
176/// Compile-time type information about generic lifetimes.
177#[derive(Debug)]
178#[non_exhaustive]
179#[unstable(feature = "type_info", issue = "146922")]
180pub struct Lifetime {
181 // No additional information to provide for now.
182}
183
184/// Compile-time type information about instantiated generic types.
185#[derive(Debug)]
186#[non_exhaustive]
187#[unstable(feature = "type_info", issue = "146922")]
188pub struct GenericType {
189 /// The type itself.
190 pub ty: TypeId,
191}
192
193/// Compile-time type information about generic const parameters.
194#[derive(Debug)]
195#[non_exhaustive]
196#[unstable(feature = "type_info", issue = "146922")]
197pub struct Const {
198 /// The const's type.
199 pub ty: TypeId,
200}
201
202/// Compile-time type information about string slice types.
203#[derive(Debug)]
204#[non_exhaustive]
205#[unstable(feature = "type_info", issue = "146922")]
206pub struct Str {
207 // No additional information to provide for now.
208}
209
210/// Compile-time type information about references.
211#[derive(Debug)]
212#[non_exhaustive]
213#[unstable(feature = "type_info", issue = "146922")]
214pub struct Reference {
215 /// The type of the value being referred to.
216 pub pointee: TypeId,
217 /// Whether this reference is mutable or not.
218 pub mutable: bool,
219}
220
221/// Compile-time type information about pointers.
222#[derive(Debug)]
223#[non_exhaustive]
224#[unstable(feature = "type_info", issue = "146922")]
225pub struct Pointer {
226 /// The type of the value being pointed to.
227 pub pointee: TypeId,
228 /// Whether this pointer is mutable or not.
229 pub mutable: bool,
230}
231
232#[derive(Debug)]
233#[unstable(feature = "type_info", issue = "146922")]
234/// Function pointer, e.g. fn(u8),
235pub struct FnPtr {
236 /// Unsafety, true is unsafe
237 pub unsafety: bool,
238
239 /// Abi, e.g. extern "C"
240 pub abi: Abi,
241
242 /// Function inputs
243 pub inputs: &'static [TypeId],
244
245 /// Function return type, default is TypeId::of::<()>
246 pub output: TypeId,
247
248 /// Vardiadic function, e.g. extern "C" fn add(n: usize, mut args: ...);
249 pub variadic: bool,
250
251 // FIXME(splat): should these fields be private, or merged into an Option<u8/u16>?
252 /// Is any function argument splatted?
253 pub is_splatted: bool,
254
255 /// The index of the splatted function argument in `inputs`, only valid if `is_splatted` is true.
256 /// e.g. in `fn overload(a: u8, #[rustc_splat] b: (f32, usize))` the index is 1, and it can be called
257 /// as `overload(a, 1.0, 2)`.
258 pub splatted_index: u8,
259}
260
261impl FnPtr {
262 /// Returns the splatted function argument index, or `None` if no argument is splatted.
263 pub const fn splatted(&self) -> Option<u8> {
264 if self.is_splatted { Some(self.splatted_index) } else { None }
265 }
266}
267
268#[derive(Debug, Default)]
269#[non_exhaustive]
270#[unstable(feature = "type_info", issue = "146922")]
271/// Abi of [FnPtr]
272pub enum Abi {
273 /// Named abi, e.g. extern "custom", "stdcall" etc.
274 Named(&'static str),
275
276 /// Default
277 #[default]
278 ExternRust,
279
280 /// C-calling convention
281 ExternC,
282}
283
284impl TypeId {
285 /// Returns `true` if the type represented by this `TypeId` is an signed integer.
286 ///
287 /// For everything else this returns false.
288 ///
289 /// # Examples
290 ///
291 /// ```
292 /// #![feature(type_info)]
293 /// use std::any::TypeId;
294 ///
295 /// assert_eq!(const { TypeId::of::<i32>().is_signed() }, true);
296 /// assert_eq!(const { TypeId::of::<u8>().is_signed() }, false);
297 /// assert_eq!(const { TypeId::of::<bool>().is_signed() }, false);
298 /// ```
299 #[unstable(feature = "type_info", issue = "146922")]
300 #[rustc_const_unstable(feature = "type_info", issue = "146922")]
301 #[rustc_comptime]
302 pub fn is_signed(self) -> bool {
303 intrinsics::type_id_is_signed(self)
304 }
305
306 /// Returns the size of the type represented by this `TypeId`. `None` if it is unsized.
307 ///
308 /// # Examples
309 ///
310 /// ```
311 /// #![feature(type_info)]
312 /// use std::any::TypeId;
313 ///
314 /// assert_eq!(const { TypeId::of::<u32>().size() }, Some(4));
315 /// assert_eq!(const { TypeId::of::<[u8; 16]>().size() }, Some(16));
316 /// ```
317 #[unstable(feature = "type_info", issue = "146922")]
318 #[rustc_const_unstable(feature = "type_info", issue = "146922")]
319 #[rustc_comptime]
320 pub fn size(self) -> Option<usize> {
321 intrinsics::size_of_type_id(self)
322 }
323
324 /// Returns the number of variants of the type represented by this `TypeId`.
325 ///
326 /// For enums, this is the number of variants. For structs and unions, this is always 1.
327 ///
328 /// ```
329 /// #![feature(type_info)]
330 /// use std::any::TypeId;
331 ///
332 /// assert_eq!(const { TypeId::of::<Option<()>>().variants() }, 2);
333 ///
334 /// struct Unit;
335 /// struct Point {
336 /// x: u32,
337 /// y: u32,
338 /// }
339 /// assert_eq!(const { TypeId::of::<Unit>().variants() }, 1);
340 /// assert_eq!(const { TypeId::of::<Point>().variants() }, 1);
341 /// assert_eq!(const { TypeId::of::<(f32, f32)>().variants() }, 1);
342 /// ```
343 #[unstable(feature = "type_info", issue = "146922")]
344 #[rustc_const_unstable(feature = "type_info", issue = "146922")]
345 #[rustc_comptime]
346 pub fn variants(self) -> usize {
347 intrinsics::type_id_variants(self)
348 }
349
350 // FIXME(reflection): make the errors nicer. This is a wider problem,
351 // TypeId::fields has nice errors in the docs but those are not the ones shown
352 // by rustc.
353 /// Returns the variant representing type at the given index of the type represented by this `TypeId`. Use it to
354 /// get the name of an enum variant or check whether it is non_exhaustive.
355 ///
356 /// ```
357 /// #![feature(type_info)]
358 /// use std::any::TypeId;
359 ///
360 /// enum Enum {
361 /// Unit,
362 /// Tuple(u32, u64),
363 /// #[non_exhaustive]
364 /// Struct { x: u32, y: u32, z: String },
365 /// }
366 /// assert_eq!(const { TypeId::of::<Enum>().variant(1).name() }, "Tuple");
367 /// assert_eq!(const { TypeId::of::<Enum>().variant(2).name() }, "Struct");
368 ///
369 /// assert_eq!(const { TypeId::of::<Enum>().variant(1).non_exhaustive() }, false);
370 /// assert_eq!(const { TypeId::of::<Enum>().variant(2).non_exhaustive() }, true);
371 /// ```
372 ///
373 /// The variant index refer to the source order index of a variant in a type.
374 ///
375 /// Variant indexes are always `0..variant_count`, regardless of any custom discriminants that may have been defined.
376 ///
377 /// ```
378 /// enum Enum {
379 /// Foo, // variant index == 0
380 /// Bar, // variant index == 1
381 /// }
382 /// ```
383 ///
384 /// Calling variant on the TypeId for a struct will be treated as a compile-time error. The same
385 /// is true for out-of-bounds indexing on an enum.
386 ///
387 /// ```compile_fail,E0080
388 /// # #![feature(type_info)]
389 /// # use std::any::TypeId;
390 /// #
391 /// # struct Point {
392 /// # x: u32,
393 /// # y: u32,
394 /// # }
395 /// # enum Enum {
396 /// # Unit,
397 /// # Tuple(u32, u64),
398 /// # Struct { x: u32, y: u32, z: String },
399 /// # }
400 /// const {
401 /// _ = TypeId::of::<Point>().variant(0); // error: cannot get the variant of a struct
402 /// _ = TypeId::of::<Enum>().variant(10); // error: indexing out of bounds: the len is 3 but the index is 10
403 /// }
404 /// ```
405 #[unstable(feature = "type_info", issue = "146922")]
406 #[rustc_const_unstable(feature = "type_info", issue = "146922")]
407 #[rustc_comptime]
408 pub fn variant(self, variant_index: usize) -> VariantId {
409 intrinsics::type_id_fields(self, variant_index);
410 VariantId { base: self, variant: variant_index }
411 }
412
413 /// Returns the number of fields at the given `variant_index` of the type represented by this `TypeId`.
414 ///
415 /// ```
416 /// #![feature(type_info)]
417 /// use std::any::TypeId;
418 ///
419 /// assert_eq!(const { TypeId::of::<u32>().fields(0) }, 0);
420 ///
421 /// struct Point {
422 /// x: u32,
423 /// y: u32,
424 /// }
425 /// assert_eq!(const { TypeId::of::<Point>().fields(0) }, 2);
426 ///
427 /// enum Enum {
428 /// Unit,
429 /// Tuple(u32, u64),
430 /// Struct { x: u32, y: u32, z: String },
431 /// }
432 /// assert_eq!(const { TypeId::of::<Enum>().fields(0) }, 0);
433 /// assert_eq!(const { TypeId::of::<Enum>().fields(1) }, 2);
434 /// assert_eq!(const { TypeId::of::<Enum>().fields(2) }, 3);
435 /// ```
436 ///
437 /// The variant index refers to the source order index of a variant in a type.
438 ///
439 /// For enums, these are always `0..variant_count`, regardless of any custom discriminants that may have been defined.
440 /// `struct`s, `tuples`, and `unions`s are considered to have a single variant with variant index zero.
441 ///
442 /// ```
443 /// enum Number {
444 /// Seven = 7, // variant index == 0
445 /// Six = 6, // variant index == 1
446 /// }
447 /// ```
448 ///
449 /// Out-of-bounds indexing will be treated as a compile-time error.
450 ///
451 /// ```compile_fail,E0080
452 /// # #![feature(type_info)]
453 /// # use std::any::TypeId;
454 /// #
455 /// # struct Point {
456 /// # x: u32,
457 /// # y: u32,
458 /// # }
459 /// # enum Enum {
460 /// # Unit,
461 /// # Tuple(u32, u64),
462 /// # Struct { x: u32, y: u32, z: String },
463 /// # }
464 /// const {
465 /// _ = TypeId::of::<Point>().fields(10); // error: indexing out of bounds: the len is 2 but the index is 10
466 /// _ = TypeId::of::<Enum>().fields(10); // error: indexing out of bounds: the len is 3 but the index is 10
467 /// }
468 /// ```
469 #[unstable(feature = "type_info", issue = "146922")]
470 #[rustc_const_unstable(feature = "type_info", issue = "146922")]
471 #[rustc_comptime]
472 // FIXME(type_info): Add enum variant pattern types and use them to represent individual variants
473 // Then add a `variant` method to get a wrapper around such a pattern type (similar to the FRT
474 // type we have) and add methods on that. It's the only way to really sensibly represent
475 // things like `non_exhaustive` which can be applied to variants as well.
476 pub fn fields(self, variant_index: usize) -> usize {
477 intrinsics::type_id_fields(self, variant_index)
478 }
479
480 /// Returns the field representing type at the given index of the type represented by this `TypeId`.
481 ///
482 /// ```
483 /// #![feature(type_info)]
484 /// use std::any::TypeId;
485 ///
486 /// struct Point {
487 /// x: u32,
488 /// y: u32,
489 /// }
490 /// assert_eq!(const { TypeId::of::<Point>().field(0, 0).type_id() }, TypeId::of::<u32>());
491 /// assert_eq!(const { TypeId::of::<Point>().field(0, 1).type_id() }, TypeId::of::<u32>());
492 ///
493 /// enum Enum {
494 /// Unit,
495 /// Tuple(u32, u64),
496 /// Struct { x: u32, y: u32, z: String },
497 /// }
498 /// assert_eq!(const { TypeId::of::<Enum>().field(1, 0).type_id() }, TypeId::of::<u32>());
499 /// assert_eq!(const { TypeId::of::<Enum>().field(2, 2).type_id() }, TypeId::of::<String>());
500 /// ```
501 ///
502 /// The variant index and field index refer to the source order index of a variant in a type and
503 /// the source order index of a field in a variant, respectively.
504 ///
505 /// For enums, variant indexes are always `0..variant_count`, regardless of any custom discriminants that may have been defined.
506 /// `struct`s, `tuples`, and `unions`s are considered to have a single variant with variant index zero.
507 ///
508 /// As for field indexes, they may not be the same as the layout order for `repr(Rust)` types, but they are for `repr(C)` types.
509 ///
510 /// ```
511 /// enum Enum {
512 /// Foo, // variant index == 0
513 /// Bar { // variant index == 1
514 /// a: (), // field index == 0 in `Bar`
515 /// b: (), // field index == 1 in `Bar`
516 /// }
517 /// }
518 /// ```
519 ///
520 /// Out-of-bounds indexing will be treated as a compile-time error.
521 ///
522 /// ```compile_fail,E0080
523 /// # #![feature(type_info)]
524 /// # use std::any::TypeId;
525 /// #
526 /// # struct Point {
527 /// # x: u32,
528 /// # y: u32,
529 /// # }
530 /// # enum Enum {
531 /// # Unit,
532 /// # Tuple(u32, u64),
533 /// # Struct { x: u32, y: u32, z: String },
534 /// # }
535 /// const {
536 /// _ = TypeId::of::<Point>().field(0, 10); // error: indexing out of bounds: the len is 2 but the index is 10
537 /// _ = TypeId::of::<Enum>().field(2, 10); // error: indexing out of bounds: the len is 3 but the index is 10
538 /// }
539 /// ```
540 #[unstable(feature = "type_info", issue = "146922")]
541 #[rustc_const_unstable(feature = "type_info", issue = "146922")]
542 #[rustc_comptime]
543 pub fn field(self, variant_index: usize, field_index: usize) -> FieldId {
544 FieldId {
545 frt_type_id: intrinsics::type_id_field_representing_type(
546 self,
547 variant_index,
548 field_index,
549 ),
550 }
551 }
552
553 /// Returns whether a type is marked with `#[non_exhaustive]`.
554 /// Returns `false` for everything but adts.
555 #[unstable(feature = "type_info", issue = "146922")]
556 #[rustc_const_unstable(feature = "type_info", issue = "146922")]
557 #[rustc_comptime]
558 pub fn non_exhaustive(self) -> bool {
559 intrinsics::non_exhaustive(self)
560 }
561
562 /// Returns a list of generic parameters of the type.
563 /// Returns an empty slice for everything that doesn't have generics.
564 #[unstable(feature = "type_info", issue = "146922")]
565 #[rustc_const_unstable(feature = "type_info", issue = "146922")]
566 #[rustc_comptime]
567 pub fn generics(self) -> &'static [Generic] {
568 intrinsics::type_id_generics(self)
569 }
570}
571
572/// Variant representing type ID. Representing a variant of an enum.
573#[derive(Copy, PartialOrd, Ord, Hash)]
574#[derive_const(Clone, PartialEq, Eq)]
575#[unstable(feature = "type_info", issue = "146922")]
576pub struct VariantId {
577 base: TypeId,
578 variant: usize,
579}
580
581#[unstable(feature = "type_info", issue = "146922")]
582impl fmt::Debug for VariantId {
583 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
584 write!(f, "Variant({:#034x}-{})", self.base.as_u128(), self.variant)
585 }
586}
587
588impl VariantId {
589 /// Returns the name of the variant.
590 ///
591 /// ```
592 /// #![feature(type_info)]
593 /// use std::any::TypeId;
594 ///
595 /// enum Enum {
596 /// Unit,
597 /// Tuple(bool),
598 /// Struct { a: bool },
599 /// }
600 /// assert_eq!(
601 /// const { TypeId::of::<Enum>().variant(1).name() },
602 /// "Tuple",
603 /// );
604 /// ```
605 #[unstable(feature = "type_info", issue = "146922")]
606 #[rustc_const_unstable(feature = "type_info", issue = "146922")]
607 #[rustc_comptime]
608 pub fn name(self) -> &'static str {
609 intrinsics::variant_name(self.base, self.variant)
610 }
611
612 /// Returns whether this variant is marked with `#[non_exhaustive]`.
613 #[unstable(feature = "type_info", issue = "146922")]
614 #[rustc_const_unstable(feature = "type_info", issue = "146922")]
615 #[rustc_comptime]
616 pub fn non_exhaustive(self) -> bool {
617 intrinsics::variant_non_exhaustive(self.base, self.variant)
618 }
619}
620
621/// Field representing type ID. Representing a field of a struct, tuple or enum variant.
622#[derive(Copy, PartialOrd, Ord, Hash)]
623#[derive_const(Clone, PartialEq, Eq)]
624#[unstable(feature = "type_info", issue = "146922")]
625pub struct FieldId {
626 frt_type_id: TypeId,
627}
628
629#[unstable(feature = "type_info", issue = "146922")]
630impl fmt::Debug for FieldId {
631 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
632 write!(f, "FieldId({:#034x})", self.frt_type_id.as_u128())
633 }
634}
635
636impl FieldId {
637 /// Returns the `TypeId` of the actual field type.
638 ///
639 /// ```
640 /// #![feature(type_info)]
641 /// use std::any::TypeId;
642 ///
643 /// struct Point {
644 /// x: u32,
645 /// y: u32,
646 /// }
647 /// assert_eq!(
648 /// const { TypeId::of::<Point>().field(0, 0).type_id() },
649 /// TypeId::of::<u32>()
650 /// );
651 /// ```
652 #[unstable(feature = "type_info", issue = "146922")]
653 #[rustc_const_unstable(feature = "type_info", issue = "146922")]
654 #[rustc_comptime]
655 pub fn type_id(self) -> TypeId {
656 intrinsics::field_representing_type_actual_type_id(self.frt_type_id)
657 }
658
659 /// Returns the name of the field.
660 ///
661 /// ```
662 /// #![feature(type_info)]
663 /// use std::any::TypeId;
664 ///
665 /// struct Point {
666 /// x: u32,
667 /// y: u32,
668 /// }
669 /// assert_eq!(
670 /// const { TypeId::of::<Point>().field(0, 0).name() },
671 /// "x",
672 /// );
673 /// ```
674 #[unstable(feature = "type_info", issue = "146922")]
675 #[rustc_const_unstable(feature = "type_info", issue = "146922")]
676 #[rustc_comptime]
677 pub fn name(self) -> &'static str {
678 intrinsics::field_representing_type_name(self.frt_type_id)
679 }
680 /// Returns the offset of the field wrt to its containing type.
681 ///
682 /// ```
683 /// #![feature(type_info)]
684 /// use std::any::TypeId;
685 ///
686 /// #[repr(C)]
687 /// struct Point {
688 /// x: u32,
689 /// y: u32,
690 /// }
691 /// assert_eq!(
692 /// const { TypeId::of::<Point>().field(0, 1).offset() },
693 /// 4,
694 /// );
695 /// ```
696 #[unstable(feature = "type_info", issue = "146922")]
697 #[rustc_const_unstable(feature = "type_info", issue = "146922")]
698 #[rustc_comptime]
699 pub fn offset(self) -> usize {
700 intrinsics::field_representing_type_offset(self.frt_type_id)
701 }
702}