core/any.rs
1//! Utilities for dynamic typing or type reflection.
2//!
3//! # `Any` and `TypeId`
4//!
5//! `Any` itself can be used to get a `TypeId`, and has more features when used
6//! as a trait object. As `&dyn Any` (a borrowed trait object), it has the `is`
7//! and `downcast_ref` methods, to test if the contained value is of a given type,
8//! and to get a reference to the inner value as a type. As `&mut dyn Any`, there
9//! is also the `downcast_mut` method, for getting a mutable reference to the
10//! inner value. `Box<dyn Any>` adds the `downcast` method, which attempts to
11//! convert to a `Box<T>`. See the [`Box`] documentation for the full details.
12//!
13//! Note that `&dyn Any` is limited to testing whether a value is of a specified
14//! concrete type, and cannot be used to test whether a type implements a trait.
15//!
16//! [`Box`]: ../../std/boxed/struct.Box.html
17//!
18//! # Smart pointers and `dyn Any`
19//!
20//! One piece of behavior to keep in mind when using `Any` as a trait object,
21//! especially with types like `Box<dyn Any>` or `Arc<dyn Any>`, is that simply
22//! calling `.type_id()` on the value will produce the `TypeId` of the
23//! *container*, not the underlying trait object. This can be avoided by
24//! converting the smart pointer into a `&dyn Any` instead, which will return
25//! the object's `TypeId`. For example:
26//!
27//! ```
28//! use std::any::{Any, TypeId};
29//!
30//! let boxed: Box<dyn Any> = Box::new(3_i32);
31//!
32//! // You're more likely to want this:
33//! let actual_id = (&*boxed).type_id();
34//! // ... than this:
35//! let boxed_id = boxed.type_id();
36//!
37//! assert_eq!(actual_id, TypeId::of::<i32>());
38//! assert_eq!(boxed_id, TypeId::of::<Box<dyn Any>>());
39//! ```
40//!
41//! ## Examples
42//!
43//! Consider a situation where we want to log a value passed to a function.
44//! We know the value we're working on implements `Debug`, but we don't know its
45//! concrete type. We want to give special treatment to certain types: in this
46//! case printing out the length of `String` values prior to their value.
47//! We don't know the concrete type of our value at compile time, so we need to
48//! use runtime reflection instead.
49//!
50//! ```rust
51//! use std::fmt::Debug;
52//! use std::any::Any;
53//!
54//! // Logger function for any type that implements `Debug`.
55//! fn log<T: Any + Debug>(value: &T) {
56//! let value_any = value as &dyn Any;
57//!
58//! // Try to convert our value to a `String`. If successful, we want to
59//! // output the `String`'s length as well as its value. If not, it's a
60//! // different type: just print it out unadorned.
61//! match value_any.downcast_ref::<String>() {
62//! Some(as_string) => {
63//! println!("String ({}): {}", as_string.len(), as_string);
64//! }
65//! None => {
66//! println!("{value:?}");
67//! }
68//! }
69//! }
70//!
71//! // This function wants to log its parameter out prior to doing work with it.
72//! fn do_work<T: Any + Debug>(value: &T) {
73//! log(value);
74//! // ...do some other work
75//! }
76//!
77//! fn main() {
78//! let my_string = "Hello World".to_string();
79//! do_work(&my_string);
80//!
81//! let my_i8: i8 = 100;
82//! do_work(&my_i8);
83//! }
84//! ```
85//!
86
87#![stable(feature = "rust1", since = "1.0.0")]
88
89#[cfg(not(feature = "ferrocene_subset"))]
90use crate::intrinsics::{self, type_id_vtable};
91#[cfg(not(feature = "ferrocene_subset"))]
92use crate::mem::transmute;
93#[cfg(not(feature = "ferrocene_subset"))]
94use crate::mem::type_info::{TraitImpl, TypeKind};
95#[cfg(not(feature = "ferrocene_subset"))]
96use crate::{fmt, hash, ptr};
97
98// Ferrocene addition: imports for certified subset
99#[cfg(feature = "ferrocene_subset")]
100#[rustfmt::skip]
101use crate::{fmt, intrinsics};
102
103///////////////////////////////////////////////////////////////////////////////
104// Any trait
105///////////////////////////////////////////////////////////////////////////////
106
107/// A trait to emulate dynamic typing.
108///
109/// Most types implement `Any`. However, any type which contains a non-`'static` reference does not.
110/// See the [module-level documentation][mod] for more details.
111///
112/// [mod]: crate::any
113// This trait is not unsafe, though we rely on the specifics of it's sole impl's
114// `type_id` function in unsafe code (e.g., `downcast`). Normally, that would be
115// a problem, but because the only impl of `Any` is a blanket implementation, no
116// other code can implement `Any`.
117//
118// We could plausibly make this trait unsafe -- it would not cause breakage,
119// since we control all the implementations -- but we choose not to as that's
120// both not really necessary and may confuse users about the distinction of
121// unsafe traits and unsafe methods (i.e., `type_id` would still be safe to call,
122// but we would likely want to indicate as such in documentation).
123#[stable(feature = "rust1", since = "1.0.0")]
124#[rustc_diagnostic_item = "Any"]
125pub trait Any: 'static {
126 /// Gets the `TypeId` of `self`.
127 ///
128 /// If called on a `dyn Any` trait object
129 /// (or a trait object of a subtrait of `Any`),
130 /// this returns the `TypeId` of the underlying
131 /// concrete type, not that of `dyn Any` itself.
132 ///
133 /// # Examples
134 ///
135 /// ```
136 /// use std::any::{Any, TypeId};
137 ///
138 /// fn is_string(s: &dyn Any) -> bool {
139 /// TypeId::of::<String>() == s.type_id()
140 /// }
141 ///
142 /// assert_eq!(is_string(&0), false);
143 /// assert_eq!(is_string(&"cookie monster".to_string()), true);
144 /// ```
145 #[stable(feature = "get_type_id", since = "1.34.0")]
146 fn type_id(&self) -> TypeId;
147}
148
149#[stable(feature = "rust1", since = "1.0.0")]
150#[cfg(not(feature = "ferrocene_subset"))]
151impl<T: 'static + ?Sized> Any for T {
152 fn type_id(&self) -> TypeId {
153 TypeId::of::<T>()
154 }
155}
156
157///////////////////////////////////////////////////////////////////////////////
158// Extension methods for Any trait objects.
159///////////////////////////////////////////////////////////////////////////////
160
161#[stable(feature = "rust1", since = "1.0.0")]
162impl fmt::Debug for dyn Any {
163 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
164 f.debug_struct("Any").finish_non_exhaustive()
165 }
166}
167
168// Ensure that the result of e.g., joining a thread can be printed and
169// hence used with `unwrap`. May eventually no longer be needed if
170// dispatch works with upcasting.
171#[stable(feature = "rust1", since = "1.0.0")]
172impl fmt::Debug for dyn Any + Send {
173 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174 f.debug_struct("Any").finish_non_exhaustive()
175 }
176}
177
178#[stable(feature = "any_send_sync_methods", since = "1.28.0")]
179impl fmt::Debug for dyn Any + Send + Sync {
180 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
181 f.debug_struct("Any").finish_non_exhaustive()
182 }
183}
184
185#[cfg(not(feature = "ferrocene_subset"))]
186impl dyn Any {
187 /// Returns `true` if the inner type is the same as `T`.
188 ///
189 /// # Examples
190 ///
191 /// ```
192 /// use std::any::Any;
193 ///
194 /// fn is_string(s: &dyn Any) {
195 /// if s.is::<String>() {
196 /// println!("It's a string!");
197 /// } else {
198 /// println!("Not a string...");
199 /// }
200 /// }
201 ///
202 /// is_string(&0);
203 /// is_string(&"cookie monster".to_string());
204 /// ```
205 #[stable(feature = "rust1", since = "1.0.0")]
206 #[inline]
207 pub fn is<T: Any>(&self) -> bool {
208 // Get `TypeId` of the type this function is instantiated with.
209 let t = TypeId::of::<T>();
210
211 // Get `TypeId` of the type in the trait object (`self`).
212 let concrete = self.type_id();
213
214 // Compare both `TypeId`s on equality.
215 t == concrete
216 }
217
218 /// Returns some reference to the inner value if it is of type `T`, or
219 /// `None` if it isn't.
220 ///
221 /// # Examples
222 ///
223 /// ```
224 /// use std::any::Any;
225 ///
226 /// fn print_if_string(s: &dyn Any) {
227 /// if let Some(string) = s.downcast_ref::<String>() {
228 /// println!("It's a string({}): '{}'", string.len(), string);
229 /// } else {
230 /// println!("Not a string...");
231 /// }
232 /// }
233 ///
234 /// print_if_string(&0);
235 /// print_if_string(&"cookie monster".to_string());
236 /// ```
237 #[stable(feature = "rust1", since = "1.0.0")]
238 #[inline]
239 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
240 if self.is::<T>() {
241 // SAFETY: just checked whether we are pointing to the correct type, and we can rely on
242 // that check for memory safety because we have implemented Any for all types; no other
243 // impls can exist as they would conflict with our impl.
244 unsafe { Some(self.downcast_unchecked_ref()) }
245 } else {
246 None
247 }
248 }
249
250 /// Returns some mutable reference to the inner value if it is of type `T`, or
251 /// `None` if it isn't.
252 ///
253 /// # Examples
254 ///
255 /// ```
256 /// use std::any::Any;
257 ///
258 /// fn modify_if_u32(s: &mut dyn Any) {
259 /// if let Some(num) = s.downcast_mut::<u32>() {
260 /// *num = 42;
261 /// }
262 /// }
263 ///
264 /// let mut x = 10u32;
265 /// let mut s = "starlord".to_string();
266 ///
267 /// modify_if_u32(&mut x);
268 /// modify_if_u32(&mut s);
269 ///
270 /// assert_eq!(x, 42);
271 /// assert_eq!(&s, "starlord");
272 /// ```
273 #[stable(feature = "rust1", since = "1.0.0")]
274 #[inline]
275 pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
276 if self.is::<T>() {
277 // SAFETY: just checked whether we are pointing to the correct type, and we can rely on
278 // that check for memory safety because we have implemented Any for all types; no other
279 // impls can exist as they would conflict with our impl.
280 unsafe { Some(self.downcast_unchecked_mut()) }
281 } else {
282 None
283 }
284 }
285
286 /// Returns a reference to the inner value as type `dyn T`.
287 ///
288 /// # Examples
289 ///
290 /// ```
291 /// #![feature(downcast_unchecked)]
292 ///
293 /// use std::any::Any;
294 ///
295 /// let x: Box<dyn Any> = Box::new(1_usize);
296 ///
297 /// unsafe {
298 /// assert_eq!(*x.downcast_unchecked_ref::<usize>(), 1);
299 /// }
300 /// ```
301 ///
302 /// # Safety
303 ///
304 /// The contained value must be of type `T`. Calling this method
305 /// with the incorrect type is *undefined behavior*.
306 #[unstable(feature = "downcast_unchecked", issue = "90850")]
307 #[inline]
308 pub unsafe fn downcast_unchecked_ref<T: Any>(&self) -> &T {
309 debug_assert!(self.is::<T>());
310 // SAFETY: caller guarantees that T is the correct type
311 unsafe { &*(self as *const dyn Any as *const T) }
312 }
313
314 /// Returns a mutable reference to the inner value as type `dyn T`.
315 ///
316 /// # Examples
317 ///
318 /// ```
319 /// #![feature(downcast_unchecked)]
320 ///
321 /// use std::any::Any;
322 ///
323 /// let mut x: Box<dyn Any> = Box::new(1_usize);
324 ///
325 /// unsafe {
326 /// *x.downcast_unchecked_mut::<usize>() += 1;
327 /// }
328 ///
329 /// assert_eq!(*x.downcast_ref::<usize>().unwrap(), 2);
330 /// ```
331 ///
332 /// # Safety
333 ///
334 /// The contained value must be of type `T`. Calling this method
335 /// with the incorrect type is *undefined behavior*.
336 #[unstable(feature = "downcast_unchecked", issue = "90850")]
337 #[inline]
338 pub unsafe fn downcast_unchecked_mut<T: Any>(&mut self) -> &mut T {
339 debug_assert!(self.is::<T>());
340 // SAFETY: caller guarantees that T is the correct type
341 unsafe { &mut *(self as *mut dyn Any as *mut T) }
342 }
343}
344
345#[cfg(not(feature = "ferrocene_subset"))]
346impl dyn Any + Send {
347 /// Forwards to the method defined on the type `dyn Any`.
348 ///
349 /// # Examples
350 ///
351 /// ```
352 /// use std::any::Any;
353 ///
354 /// fn is_string(s: &(dyn Any + Send)) {
355 /// if s.is::<String>() {
356 /// println!("It's a string!");
357 /// } else {
358 /// println!("Not a string...");
359 /// }
360 /// }
361 ///
362 /// is_string(&0);
363 /// is_string(&"cookie monster".to_string());
364 /// ```
365 #[stable(feature = "rust1", since = "1.0.0")]
366 #[inline]
367 pub fn is<T: Any>(&self) -> bool {
368 <dyn Any>::is::<T>(self)
369 }
370
371 /// Forwards to the method defined on the type `dyn Any`.
372 ///
373 /// # Examples
374 ///
375 /// ```
376 /// use std::any::Any;
377 ///
378 /// fn print_if_string(s: &(dyn Any + Send)) {
379 /// if let Some(string) = s.downcast_ref::<String>() {
380 /// println!("It's a string({}): '{}'", string.len(), string);
381 /// } else {
382 /// println!("Not a string...");
383 /// }
384 /// }
385 ///
386 /// print_if_string(&0);
387 /// print_if_string(&"cookie monster".to_string());
388 /// ```
389 #[stable(feature = "rust1", since = "1.0.0")]
390 #[inline]
391 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
392 <dyn Any>::downcast_ref::<T>(self)
393 }
394
395 /// Forwards to the method defined on the type `dyn Any`.
396 ///
397 /// # Examples
398 ///
399 /// ```
400 /// use std::any::Any;
401 ///
402 /// fn modify_if_u32(s: &mut (dyn Any + Send)) {
403 /// if let Some(num) = s.downcast_mut::<u32>() {
404 /// *num = 42;
405 /// }
406 /// }
407 ///
408 /// let mut x = 10u32;
409 /// let mut s = "starlord".to_string();
410 ///
411 /// modify_if_u32(&mut x);
412 /// modify_if_u32(&mut s);
413 ///
414 /// assert_eq!(x, 42);
415 /// assert_eq!(&s, "starlord");
416 /// ```
417 #[stable(feature = "rust1", since = "1.0.0")]
418 #[inline]
419 pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
420 <dyn Any>::downcast_mut::<T>(self)
421 }
422
423 /// Forwards to the method defined on the type `dyn Any`.
424 ///
425 /// # Examples
426 ///
427 /// ```
428 /// #![feature(downcast_unchecked)]
429 ///
430 /// use std::any::Any;
431 ///
432 /// let x: Box<dyn Any> = Box::new(1_usize);
433 ///
434 /// unsafe {
435 /// assert_eq!(*x.downcast_unchecked_ref::<usize>(), 1);
436 /// }
437 /// ```
438 ///
439 /// # Safety
440 ///
441 /// The contained value must be of type `T`. Calling this method
442 /// with the incorrect type is *undefined behavior*.
443 #[unstable(feature = "downcast_unchecked", issue = "90850")]
444 #[inline]
445 pub unsafe fn downcast_unchecked_ref<T: Any>(&self) -> &T {
446 // SAFETY: guaranteed by caller
447 unsafe { <dyn Any>::downcast_unchecked_ref::<T>(self) }
448 }
449
450 /// Forwards to the method defined on the type `dyn Any`.
451 ///
452 /// # Examples
453 ///
454 /// ```
455 /// #![feature(downcast_unchecked)]
456 ///
457 /// use std::any::Any;
458 ///
459 /// let mut x: Box<dyn Any> = Box::new(1_usize);
460 ///
461 /// unsafe {
462 /// *x.downcast_unchecked_mut::<usize>() += 1;
463 /// }
464 ///
465 /// assert_eq!(*x.downcast_ref::<usize>().unwrap(), 2);
466 /// ```
467 ///
468 /// # Safety
469 ///
470 /// The contained value must be of type `T`. Calling this method
471 /// with the incorrect type is *undefined behavior*.
472 #[unstable(feature = "downcast_unchecked", issue = "90850")]
473 #[inline]
474 pub unsafe fn downcast_unchecked_mut<T: Any>(&mut self) -> &mut T {
475 // SAFETY: guaranteed by caller
476 unsafe { <dyn Any>::downcast_unchecked_mut::<T>(self) }
477 }
478}
479
480#[cfg(not(feature = "ferrocene_subset"))]
481impl dyn Any + Send + Sync {
482 /// Forwards to the method defined on the type `Any`.
483 ///
484 /// # Examples
485 ///
486 /// ```
487 /// use std::any::Any;
488 ///
489 /// fn is_string(s: &(dyn Any + Send + Sync)) {
490 /// if s.is::<String>() {
491 /// println!("It's a string!");
492 /// } else {
493 /// println!("Not a string...");
494 /// }
495 /// }
496 ///
497 /// is_string(&0);
498 /// is_string(&"cookie monster".to_string());
499 /// ```
500 #[stable(feature = "any_send_sync_methods", since = "1.28.0")]
501 #[inline]
502 pub fn is<T: Any>(&self) -> bool {
503 <dyn Any>::is::<T>(self)
504 }
505
506 /// Forwards to the method defined on the type `Any`.
507 ///
508 /// # Examples
509 ///
510 /// ```
511 /// use std::any::Any;
512 ///
513 /// fn print_if_string(s: &(dyn Any + Send + Sync)) {
514 /// if let Some(string) = s.downcast_ref::<String>() {
515 /// println!("It's a string({}): '{}'", string.len(), string);
516 /// } else {
517 /// println!("Not a string...");
518 /// }
519 /// }
520 ///
521 /// print_if_string(&0);
522 /// print_if_string(&"cookie monster".to_string());
523 /// ```
524 #[stable(feature = "any_send_sync_methods", since = "1.28.0")]
525 #[inline]
526 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
527 <dyn Any>::downcast_ref::<T>(self)
528 }
529
530 /// Forwards to the method defined on the type `Any`.
531 ///
532 /// # Examples
533 ///
534 /// ```
535 /// use std::any::Any;
536 ///
537 /// fn modify_if_u32(s: &mut (dyn Any + Send + Sync)) {
538 /// if let Some(num) = s.downcast_mut::<u32>() {
539 /// *num = 42;
540 /// }
541 /// }
542 ///
543 /// let mut x = 10u32;
544 /// let mut s = "starlord".to_string();
545 ///
546 /// modify_if_u32(&mut x);
547 /// modify_if_u32(&mut s);
548 ///
549 /// assert_eq!(x, 42);
550 /// assert_eq!(&s, "starlord");
551 /// ```
552 #[stable(feature = "any_send_sync_methods", since = "1.28.0")]
553 #[inline]
554 pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
555 <dyn Any>::downcast_mut::<T>(self)
556 }
557
558 /// Forwards to the method defined on the type `Any`.
559 ///
560 /// # Examples
561 ///
562 /// ```
563 /// #![feature(downcast_unchecked)]
564 ///
565 /// use std::any::Any;
566 ///
567 /// let x: Box<dyn Any> = Box::new(1_usize);
568 ///
569 /// unsafe {
570 /// assert_eq!(*x.downcast_unchecked_ref::<usize>(), 1);
571 /// }
572 /// ```
573 /// # Safety
574 ///
575 /// The contained value must be of type `T`. Calling this method
576 /// with the incorrect type is *undefined behavior*.
577 #[unstable(feature = "downcast_unchecked", issue = "90850")]
578 #[inline]
579 pub unsafe fn downcast_unchecked_ref<T: Any>(&self) -> &T {
580 // SAFETY: guaranteed by caller
581 unsafe { <dyn Any>::downcast_unchecked_ref::<T>(self) }
582 }
583
584 /// Forwards to the method defined on the type `Any`.
585 ///
586 /// # Examples
587 ///
588 /// ```
589 /// #![feature(downcast_unchecked)]
590 ///
591 /// use std::any::Any;
592 ///
593 /// let mut x: Box<dyn Any> = Box::new(1_usize);
594 ///
595 /// unsafe {
596 /// *x.downcast_unchecked_mut::<usize>() += 1;
597 /// }
598 ///
599 /// assert_eq!(*x.downcast_ref::<usize>().unwrap(), 2);
600 /// ```
601 /// # Safety
602 ///
603 /// The contained value must be of type `T`. Calling this method
604 /// with the incorrect type is *undefined behavior*.
605 #[unstable(feature = "downcast_unchecked", issue = "90850")]
606 #[inline]
607 pub unsafe fn downcast_unchecked_mut<T: Any>(&mut self) -> &mut T {
608 // SAFETY: guaranteed by caller
609 unsafe { <dyn Any>::downcast_unchecked_mut::<T>(self) }
610 }
611}
612
613///////////////////////////////////////////////////////////////////////////////
614// TypeID and its methods
615///////////////////////////////////////////////////////////////////////////////
616
617/// A `TypeId` represents a globally unique identifier for a type.
618///
619/// Each `TypeId` is an opaque object which does not allow inspection of what's
620/// inside but does allow basic operations such as cloning, comparison,
621/// printing, and showing.
622///
623/// A `TypeId` is currently only available for types which ascribe to `'static`,
624/// but this limitation may be removed in the future.
625///
626/// While `TypeId` implements `Hash`, `PartialOrd`, and `Ord`, it is worth
627/// noting that the hashes and ordering will vary between Rust releases. Beware
628/// of relying on them inside of your code!
629///
630/// # Layout
631///
632/// Like other [`Rust`-representation][repr-rust] types, `TypeId`'s size and layout are unstable.
633/// In particular, this means that you cannot rely on the size and layout of `TypeId` remaining the
634/// same between Rust releases; they are subject to change without prior notice between Rust
635/// releases.
636///
637/// [repr-rust]: https://doc.rust-lang.org/reference/type-layout.html#r-layout.repr.rust.unspecified
638///
639/// # Danger of Improper Variance
640///
641/// You might think that subtyping is impossible between two static types,
642/// but this is false; there exists a static type with a static subtype.
643/// To wit, `fn(&str)`, which is short for `for<'any> fn(&'any str)`, and
644/// `fn(&'static str)`, are two distinct, static types, and yet,
645/// `fn(&str)` is a subtype of `fn(&'static str)`, since any value of type
646/// `fn(&str)` can be used where a value of type `fn(&'static str)` is needed.
647///
648/// This means that abstractions around `TypeId`, despite its
649/// `'static` bound on arguments, still need to worry about unnecessary
650/// and improper variance: it is advisable to strive for invariance
651/// first. The usability impact will be negligible, while the reduction
652/// in the risk of unsoundness will be most welcome.
653///
654/// ## Examples
655///
656/// Suppose `SubType` is a subtype of `SuperType`, that is,
657/// a value of type `SubType` can be used wherever
658/// a value of type `SuperType` is expected.
659/// Suppose also that `CoVar<T>` is a generic type, which is covariant over `T`
660/// (like many other types, including `PhantomData<T>` and `Vec<T>`).
661///
662/// Then, by covariance, `CoVar<SubType>` is a subtype of `CoVar<SuperType>`,
663/// that is, a value of type `CoVar<SubType>` can be used wherever
664/// a value of type `CoVar<SuperType>` is expected.
665///
666/// Then if `CoVar<SuperType>` relies on `TypeId::of::<SuperType>()` to uphold any invariants,
667/// those invariants may be broken because a value of type `CoVar<SuperType>` can be created
668/// without going through any of its methods, like so:
669/// ```
670/// type SubType = fn(&());
671/// type SuperType = fn(&'static ());
672/// type CoVar<T> = Vec<T>; // imagine something more complicated
673///
674/// let sub: CoVar<SubType> = CoVar::new();
675/// // we have a `CoVar<SuperType>` instance without
676/// // *ever* having called `CoVar::<SuperType>::new()`!
677/// let fake_super: CoVar<SuperType> = sub;
678/// ```
679///
680/// The following is an example program that tries to use `TypeId::of` to
681/// implement a generic type `Unique<T>` that guarantees unique instances for each `Unique<T>`,
682/// that is, and for each type `T` there can be at most one value of type `Unique<T>` at any time.
683///
684/// ```
685/// mod unique {
686/// use std::any::TypeId;
687/// use std::collections::BTreeSet;
688/// use std::marker::PhantomData;
689/// use std::sync::Mutex;
690///
691/// static ID_SET: Mutex<BTreeSet<TypeId>> = Mutex::new(BTreeSet::new());
692///
693/// // TypeId has only covariant uses, which makes Unique covariant over TypeAsId 🚨
694/// #[derive(Debug, PartialEq)]
695/// pub struct Unique<TypeAsId: 'static>(
696/// // private field prevents creation without `new` outside this module
697/// PhantomData<TypeAsId>,
698/// );
699///
700/// impl<TypeAsId: 'static> Unique<TypeAsId> {
701/// pub fn new() -> Option<Self> {
702/// let mut set = ID_SET.lock().unwrap();
703/// (set.insert(TypeId::of::<TypeAsId>())).then(|| Self(PhantomData))
704/// }
705/// }
706///
707/// impl<TypeAsId: 'static> Drop for Unique<TypeAsId> {
708/// fn drop(&mut self) {
709/// let mut set = ID_SET.lock().unwrap();
710/// (!set.remove(&TypeId::of::<TypeAsId>())).then(|| panic!("duplicity detected"));
711/// }
712/// }
713/// }
714///
715/// use unique::Unique;
716///
717/// // `OtherRing` is a subtype of `TheOneRing`. Both are 'static, and thus have a TypeId.
718/// type TheOneRing = fn(&'static ());
719/// type OtherRing = fn(&());
720///
721/// fn main() {
722/// let the_one_ring: Unique<TheOneRing> = Unique::new().unwrap();
723/// assert_eq!(Unique::<TheOneRing>::new(), None);
724///
725/// let other_ring: Unique<OtherRing> = Unique::new().unwrap();
726/// // Use that `Unique<OtherRing>` is a subtype of `Unique<TheOneRing>` 🚨
727/// let fake_one_ring: Unique<TheOneRing> = other_ring;
728/// assert_eq!(fake_one_ring, the_one_ring);
729///
730/// std::mem::forget(fake_one_ring);
731/// }
732/// ```
733#[cfg_attr(not(feature = "ferrocene_subset"), derive(Copy, PartialOrd, Ord))]
734#[cfg_attr(not(feature = "ferrocene_subset"), derive_const(Clone, Eq))]
735#[cfg_attr(feature = "ferrocene_subset", derive(Copy))]
736#[cfg_attr(feature = "ferrocene_subset", derive_const(Clone))]
737#[stable(feature = "rust1", since = "1.0.0")]
738#[lang = "type_id"]
739pub struct TypeId {
740 /// This needs to be an array of pointers, since there is provenance
741 /// in the first array field. This provenance knows exactly which type
742 /// the TypeId actually is, allowing CTFE and miri to operate based off it.
743 /// At runtime all the pointers in the array contain bits of the hash, making
744 /// the entire `TypeId` actually just be a `u128` hash of the type.
745 pub(crate) data: [*const (); 16 / size_of::<*const ()>()],
746}
747
748// SAFETY: the raw pointer is always an integer
749#[stable(feature = "rust1", since = "1.0.0")]
750unsafe impl Send for TypeId {}
751// SAFETY: the raw pointer is always an integer
752#[stable(feature = "rust1", since = "1.0.0")]
753unsafe impl Sync for TypeId {}
754
755#[stable(feature = "rust1", since = "1.0.0")]
756#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
757impl const PartialEq for TypeId {
758 #[inline]
759 fn eq(&self, other: &Self) -> bool {
760 #[cfg(miri)]
761 return crate::intrinsics::type_id_eq(*self, *other);
762 #[cfg(not(miri))]
763 {
764 let this = self;
765 crate::intrinsics::const_eval_select!(
766 @capture { this: &TypeId, other: &TypeId } -> bool:
767 if const {
768 crate::intrinsics::type_id_eq(*this, *other)
769 } else {
770 // Ideally we would just invoke `type_id_eq` unconditionally here,
771 // but since we do not MIR inline intrinsics, because backends
772 // may want to override them (and miri does!), MIR opts do not
773 // clean up this call sufficiently for LLVM to turn repeated calls
774 // of `TypeId` comparisons against one specific `TypeId` into
775 // a lookup table.
776 // SAFETY: We know that at runtime none of the bits have provenance and all bits
777 // are initialized. So we can just convert the whole thing to a `u128` and compare that.
778 unsafe {
779 crate::mem::transmute::<_, u128>(*this) == crate::mem::transmute::<_, u128>(*other)
780 }
781 }
782 )
783 }
784 }
785}
786
787impl TypeId {
788 /// Returns the `TypeId` of the generic type parameter.
789 ///
790 /// # Examples
791 ///
792 /// ```
793 /// use std::any::{Any, TypeId};
794 ///
795 /// fn is_string<T: ?Sized + Any>(_s: &T) -> bool {
796 /// TypeId::of::<String>() == TypeId::of::<T>()
797 /// }
798 ///
799 /// assert_eq!(is_string(&0), false);
800 /// assert_eq!(is_string(&"cookie monster".to_string()), true);
801 /// ```
802 #[must_use]
803 #[stable(feature = "rust1", since = "1.0.0")]
804 #[rustc_const_stable(feature = "const_type_id", since = "1.91.0")]
805 pub const fn of<T: ?Sized + 'static>() -> TypeId {
806 const { intrinsics::type_id::<T>() }
807 }
808
809 /// Checks if the [TypeId] implements the trait. If it does it returns [TraitImpl] which can be used to build a fat pointer.
810 /// It can only be called at compile time. `self` must be the [TypeId] of a sized type or None will be returned.
811 ///
812 /// # Examples
813 ///
814 /// ```
815 /// #![feature(type_info)]
816 /// use std::any::{TypeId};
817 ///
818 /// pub trait Blah {}
819 /// impl Blah for u8 {}
820 ///
821 /// assert!(const { TypeId::of::<u8>().trait_info_of::<dyn Blah>() }.is_some());
822 /// assert!(const { TypeId::of::<u16>().trait_info_of::<dyn Blah>() }.is_none());
823 /// ```
824 #[cfg(not(feature = "ferrocene_subset"))]
825 #[unstable(feature = "type_info", issue = "146922")]
826 #[rustc_const_unstable(feature = "type_info", issue = "146922")]
827 pub const fn trait_info_of<
828 T: ptr::Pointee<Metadata = ptr::DynMetadata<T>> + ?Sized + 'static,
829 >(
830 self,
831 ) -> Option<TraitImpl<T>> {
832 // SAFETY: The vtable was obtained for `T`, so it is guaranteed to be `DynMetadata<T>`.
833 // The intrinsic can't infer this because it is designed to work with arbitrary TypeIds.
834 unsafe { transmute(self.trait_info_of_trait_type_id(const { TypeId::of::<T>() })) }
835 }
836
837 /// Checks if the [TypeId] implements the trait of `trait_represented_by_type_id`. If it does it returns [TraitImpl] which can be used to build a fat pointer.
838 /// It can only be called at compile time. `self` must be the [TypeId] of a sized type or None will be returned.
839 ///
840 /// # Examples
841 ///
842 /// ```
843 /// #![feature(type_info)]
844 /// use std::any::{TypeId};
845 ///
846 /// pub trait Blah {}
847 /// impl Blah for u8 {}
848 ///
849 /// assert!(const { TypeId::of::<u8>().trait_info_of_trait_type_id(TypeId::of::<dyn Blah>()) }.is_some());
850 /// assert!(const { TypeId::of::<u16>().trait_info_of_trait_type_id(TypeId::of::<dyn Blah>()) }.is_none());
851 /// ```
852 #[cfg(not(feature = "ferrocene_subset"))]
853 #[unstable(feature = "type_info", issue = "146922")]
854 #[rustc_const_unstable(feature = "type_info", issue = "146922")]
855 pub const fn trait_info_of_trait_type_id(
856 self,
857 trait_represented_by_type_id: TypeId,
858 ) -> Option<TraitImpl<*const ()>> {
859 if self.info().size.is_none() {
860 return None;
861 }
862
863 if matches!(trait_represented_by_type_id.info().kind, TypeKind::DynTrait(_))
864 && let Some(vtable) = type_id_vtable(self, trait_represented_by_type_id)
865 {
866 Some(TraitImpl { vtable })
867 } else {
868 None
869 }
870 }
871
872 fn as_u128(self) -> u128 {
873 let mut bytes = [0; 16];
874
875 // This is a provenance-stripping memcpy.
876 for (i, chunk) in self.data.iter().copied().enumerate() {
877 let chunk = chunk.addr().to_ne_bytes();
878 let start = i * chunk.len();
879 bytes[start..(start + chunk.len())].copy_from_slice(&chunk);
880 }
881 u128::from_ne_bytes(bytes)
882 }
883}
884
885#[stable(feature = "rust1", since = "1.0.0")]
886#[cfg(not(feature = "ferrocene_subset"))]
887impl hash::Hash for TypeId {
888 #[inline]
889 fn hash<H: hash::Hasher>(&self, state: &mut H) {
890 // We only hash the lower 64 bits of our (128 bit) internal numeric ID,
891 // because:
892 // - The hashing algorithm which backs `TypeId` is expected to be
893 // unbiased and high quality, meaning further mixing would be somewhat
894 // redundant compared to choosing (the lower) 64 bits arbitrarily.
895 // - `Hasher::finish` returns a u64 anyway, so the extra entropy we'd
896 // get from hashing the full value would probably not be useful
897 // (especially given the previous point about the lower 64 bits being
898 // high quality on their own).
899 // - It is correct to do so -- only hashing a subset of `self` is still
900 // compatible with an `Eq` implementation that considers the entire
901 // value, as ours does.
902 let data =
903 // SAFETY: The `offset` stays in-bounds, it just moves the pointer to the 2nd half of the `TypeId`.
904 // Only the first ptr-sized chunk ever has provenance, so that second half is always
905 // fine to read at integer type.
906 unsafe { crate::ptr::read_unaligned(self.data.as_ptr().cast::<u64>().offset(1)) };
907 data.hash(state);
908 }
909}
910
911#[stable(feature = "rust1", since = "1.0.0")]
912impl fmt::Debug for TypeId {
913 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
914 write!(f, "TypeId({:#034x})", self.as_u128())
915 }
916}
917
918/// Returns the name of a type as a string slice.
919///
920/// # Note
921///
922/// This is intended for diagnostic use. The exact contents and format of the
923/// string returned are not specified, other than being a best-effort
924/// description of the type. For example, amongst the strings
925/// that `type_name::<Option<String>>()` might return are `"Option<String>"` and
926/// `"std::option::Option<std::string::String>"`.
927///
928/// The returned string must not be considered to be a unique identifier of a
929/// type as multiple types may map to the same type name. Similarly, there is no
930/// guarantee that all parts of a type will appear in the returned string. In
931/// addition, the output may change between versions of the compiler. For
932/// example, lifetime specifiers were omitted in some earlier versions.
933///
934/// The current implementation uses the same infrastructure as compiler
935/// diagnostics and debuginfo, but this is not guaranteed.
936///
937/// # Examples
938///
939/// ```rust
940/// assert_eq!(
941/// std::any::type_name::<Option<String>>(),
942/// "core::option::Option<alloc::string::String>",
943/// );
944/// ```
945#[must_use]
946#[stable(feature = "type_name", since = "1.38.0")]
947#[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
948pub const fn type_name<T: ?Sized>() -> &'static str {
949 const { intrinsics::type_name::<T>() }
950}
951
952/// Returns the type name of the pointed-to value as a string slice.
953///
954/// This is the same as `type_name::<T>()`, but can be used where the type of a
955/// variable is not easily available.
956///
957/// # Note
958///
959/// Like [`type_name`], this is intended for diagnostic use and the exact output is not
960/// guaranteed. It provides a best-effort description, but the output may change between
961/// versions of the compiler.
962///
963/// In short: use this for debugging, avoid using the output to affect program behavior. More
964/// information is available at [`type_name`].
965///
966/// Additionally, this function does not resolve trait objects. This means that
967/// `type_name_of_val(&7u32 as &dyn Debug)` may return `"dyn Debug"`, but will not return `"u32"`
968/// at this time.
969///
970/// # Examples
971///
972/// Prints the default integer and float types.
973///
974/// ```rust
975/// use std::any::type_name_of_val;
976///
977/// let s = "foo";
978/// let x: i32 = 1;
979/// let y: f32 = 1.0;
980///
981/// assert!(type_name_of_val(&s).contains("str"));
982/// assert!(type_name_of_val(&x).contains("i32"));
983/// assert!(type_name_of_val(&y).contains("f32"));
984/// ```
985#[must_use]
986#[stable(feature = "type_name_of_val", since = "1.76.0")]
987#[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
988pub const fn type_name_of_val<T: ?Sized>(_val: &T) -> &'static str {
989 type_name::<T>()
990}
991
992/// Returns `Some(&U)` if `T` can be coerced to the trait object type `U`. Otherwise, it returns `None`.
993///
994/// # Compile-time failures
995/// Determining whether `T` can be coerced to the trait object type `U` requires compiler trait resolution.
996/// In some cases, that resolution can exceed the recursion limit,
997/// and compilation will fail instead of this function returning `None`.
998/// # Examples
999///
1000/// ```rust
1001/// #![feature(try_as_dyn)]
1002///
1003/// use core::any::try_as_dyn;
1004///
1005/// trait Animal {
1006/// fn speak(&self) -> &'static str;
1007/// }
1008///
1009/// struct Dog;
1010/// impl Animal for Dog {
1011/// fn speak(&self) -> &'static str { "woof" }
1012/// }
1013///
1014/// struct Rock; // does not implement Animal
1015///
1016/// let dog = Dog;
1017/// let rock = Rock;
1018///
1019/// let as_animal: Option<&dyn Animal> = try_as_dyn::<Dog, dyn Animal>(&dog);
1020/// assert_eq!(as_animal.unwrap().speak(), "woof");
1021///
1022/// let not_an_animal: Option<&dyn Animal> = try_as_dyn::<Rock, dyn Animal>(&rock);
1023/// assert!(not_an_animal.is_none());
1024/// ```
1025#[cfg(not(feature = "ferrocene_subset"))]
1026#[must_use]
1027#[unstable(feature = "try_as_dyn", issue = "144361")]
1028pub const fn try_as_dyn<
1029 T: Any + 'static,
1030 U: ptr::Pointee<Metadata = ptr::DynMetadata<U>> + ?Sized + 'static,
1031>(
1032 t: &T,
1033) -> Option<&U> {
1034 let vtable: Option<ptr::DynMetadata<U>> =
1035 const { TypeId::of::<T>().trait_info_of::<U>().as_ref().map(TraitImpl::get_vtable) };
1036 match vtable {
1037 Some(dyn_metadata) => {
1038 let pointer = ptr::from_raw_parts(t, dyn_metadata);
1039 // SAFETY: `t` is a reference to a type, so we know it is valid.
1040 // `dyn_metadata` is a vtable for T, implementing the trait of `U`.
1041 Some(unsafe { &*pointer })
1042 }
1043 None => None,
1044 }
1045}
1046
1047/// Returns `Some(&mut U)` if `T` can be coerced to the trait object type `U`. Otherwise, it returns `None`.
1048///
1049/// # Compile-time failures
1050/// Determining whether `T` can be coerced to the trait object type `U` requires compiler trait resolution.
1051/// In some cases, that resolution can exceed the recursion limit,
1052/// and compilation will fail instead of this function returning `None`.
1053/// # Examples
1054///
1055/// ```rust
1056/// #![feature(try_as_dyn)]
1057///
1058/// use core::any::try_as_dyn_mut;
1059///
1060/// trait Animal {
1061/// fn speak(&self) -> &'static str;
1062/// }
1063///
1064/// struct Dog;
1065/// impl Animal for Dog {
1066/// fn speak(&self) -> &'static str { "woof" }
1067/// }
1068///
1069/// struct Rock; // does not implement Animal
1070///
1071/// let mut dog = Dog;
1072/// let mut rock = Rock;
1073///
1074/// let as_animal: Option<&mut dyn Animal> = try_as_dyn_mut::<Dog, dyn Animal>(&mut dog);
1075/// assert_eq!(as_animal.unwrap().speak(), "woof");
1076///
1077/// let not_an_animal: Option<&mut dyn Animal> = try_as_dyn_mut::<Rock, dyn Animal>(&mut rock);
1078/// assert!(not_an_animal.is_none());
1079/// ```
1080#[cfg(not(feature = "ferrocene_subset"))]
1081#[must_use]
1082#[unstable(feature = "try_as_dyn", issue = "144361")]
1083pub const fn try_as_dyn_mut<
1084 T: Any + 'static,
1085 U: ptr::Pointee<Metadata = ptr::DynMetadata<U>> + ?Sized + 'static,
1086>(
1087 t: &mut T,
1088) -> Option<&mut U> {
1089 let vtable: Option<ptr::DynMetadata<U>> =
1090 const { TypeId::of::<T>().trait_info_of::<U>().as_ref().map(TraitImpl::get_vtable) };
1091 match vtable {
1092 Some(dyn_metadata) => {
1093 let pointer = ptr::from_raw_parts_mut(t, dyn_metadata);
1094 // SAFETY: `t` is a reference to a type, so we know it is valid.
1095 // `dyn_metadata` is a vtable for T, implementing the trait of `U`.
1096 Some(unsafe { &mut *pointer })
1097 }
1098 None => None,
1099 }
1100}