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_certified"))]
90use crate::{fmt, hash, intrinsics};
91
92// Ferrocene addition: imports for certified subset
93#[cfg(feature = "ferrocene_certified")]
94#[rustfmt::skip]
95use crate::intrinsics;
96
97///////////////////////////////////////////////////////////////////////////////
98// Any trait
99///////////////////////////////////////////////////////////////////////////////
100
101/// A trait to emulate dynamic typing.
102///
103/// Most types implement `Any`. However, any type which contains a non-`'static` reference does not.
104/// See the [module-level documentation][mod] for more details.
105///
106/// [mod]: crate::any
107// This trait is not unsafe, though we rely on the specifics of it's sole impl's
108// `type_id` function in unsafe code (e.g., `downcast`). Normally, that would be
109// a problem, but because the only impl of `Any` is a blanket implementation, no
110// other code can implement `Any`.
111//
112// We could plausibly make this trait unsafe -- it would not cause breakage,
113// since we control all the implementations -- but we choose not to as that's
114// both not really necessary and may confuse users about the distinction of
115// unsafe traits and unsafe methods (i.e., `type_id` would still be safe to call,
116// but we would likely want to indicate as such in documentation).
117#[stable(feature = "rust1", since = "1.0.0")]
118#[rustc_diagnostic_item = "Any"]
119pub trait Any: 'static {
120 /// Gets the `TypeId` of `self`.
121 ///
122 /// If called on a `dyn Any` trait object
123 /// (or a trait object of a subtrait of `Any`),
124 /// this returns the `TypeId` of the underlying
125 /// concrete type, not that of `dyn Any` itself.
126 ///
127 /// # Examples
128 ///
129 /// ```
130 /// use std::any::{Any, TypeId};
131 ///
132 /// fn is_string(s: &dyn Any) -> bool {
133 /// TypeId::of::<String>() == s.type_id()
134 /// }
135 ///
136 /// assert_eq!(is_string(&0), false);
137 /// assert_eq!(is_string(&"cookie monster".to_string()), true);
138 /// ```
139 #[stable(feature = "get_type_id", since = "1.34.0")]
140 fn type_id(&self) -> TypeId;
141}
142
143#[stable(feature = "rust1", since = "1.0.0")]
144#[cfg(not(feature = "ferrocene_certified"))]
145impl<T: 'static + ?Sized> Any for T {
146 fn type_id(&self) -> TypeId {
147 TypeId::of::<T>()
148 }
149}
150
151///////////////////////////////////////////////////////////////////////////////
152// Extension methods for Any trait objects.
153///////////////////////////////////////////////////////////////////////////////
154
155#[stable(feature = "rust1", since = "1.0.0")]
156#[cfg(not(feature = "ferrocene_certified"))]
157impl fmt::Debug for dyn Any {
158 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
159 f.debug_struct("Any").finish_non_exhaustive()
160 }
161}
162
163// Ensure that the result of e.g., joining a thread can be printed and
164// hence used with `unwrap`. May eventually no longer be needed if
165// dispatch works with upcasting.
166#[stable(feature = "rust1", since = "1.0.0")]
167#[cfg(not(feature = "ferrocene_certified"))]
168impl fmt::Debug for dyn Any + Send {
169 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
170 f.debug_struct("Any").finish_non_exhaustive()
171 }
172}
173
174#[stable(feature = "any_send_sync_methods", since = "1.28.0")]
175#[cfg(not(feature = "ferrocene_certified"))]
176impl fmt::Debug for dyn Any + Send + Sync {
177 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
178 f.debug_struct("Any").finish_non_exhaustive()
179 }
180}
181
182#[cfg(not(feature = "ferrocene_certified"))]
183impl dyn Any {
184 /// Returns `true` if the inner type is the same as `T`.
185 ///
186 /// # Examples
187 ///
188 /// ```
189 /// use std::any::Any;
190 ///
191 /// fn is_string(s: &dyn Any) {
192 /// if s.is::<String>() {
193 /// println!("It's a string!");
194 /// } else {
195 /// println!("Not a string...");
196 /// }
197 /// }
198 ///
199 /// is_string(&0);
200 /// is_string(&"cookie monster".to_string());
201 /// ```
202 #[stable(feature = "rust1", since = "1.0.0")]
203 #[inline]
204 pub fn is<T: Any>(&self) -> bool {
205 // Get `TypeId` of the type this function is instantiated with.
206 let t = TypeId::of::<T>();
207
208 // Get `TypeId` of the type in the trait object (`self`).
209 let concrete = self.type_id();
210
211 // Compare both `TypeId`s on equality.
212 t == concrete
213 }
214
215 /// Returns some reference to the inner value if it is of type `T`, or
216 /// `None` if it isn't.
217 ///
218 /// # Examples
219 ///
220 /// ```
221 /// use std::any::Any;
222 ///
223 /// fn print_if_string(s: &dyn Any) {
224 /// if let Some(string) = s.downcast_ref::<String>() {
225 /// println!("It's a string({}): '{}'", string.len(), string);
226 /// } else {
227 /// println!("Not a string...");
228 /// }
229 /// }
230 ///
231 /// print_if_string(&0);
232 /// print_if_string(&"cookie monster".to_string());
233 /// ```
234 #[stable(feature = "rust1", since = "1.0.0")]
235 #[inline]
236 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
237 if self.is::<T>() {
238 // SAFETY: just checked whether we are pointing to the correct type, and we can rely on
239 // that check for memory safety because we have implemented Any for all types; no other
240 // impls can exist as they would conflict with our impl.
241 unsafe { Some(self.downcast_unchecked_ref()) }
242 } else {
243 None
244 }
245 }
246
247 /// Returns some mutable reference to the inner value if it is of type `T`, or
248 /// `None` if it isn't.
249 ///
250 /// # Examples
251 ///
252 /// ```
253 /// use std::any::Any;
254 ///
255 /// fn modify_if_u32(s: &mut dyn Any) {
256 /// if let Some(num) = s.downcast_mut::<u32>() {
257 /// *num = 42;
258 /// }
259 /// }
260 ///
261 /// let mut x = 10u32;
262 /// let mut s = "starlord".to_string();
263 ///
264 /// modify_if_u32(&mut x);
265 /// modify_if_u32(&mut s);
266 ///
267 /// assert_eq!(x, 42);
268 /// assert_eq!(&s, "starlord");
269 /// ```
270 #[stable(feature = "rust1", since = "1.0.0")]
271 #[inline]
272 pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
273 if self.is::<T>() {
274 // SAFETY: just checked whether we are pointing to the correct type, and we can rely on
275 // that check for memory safety because we have implemented Any for all types; no other
276 // impls can exist as they would conflict with our impl.
277 unsafe { Some(self.downcast_unchecked_mut()) }
278 } else {
279 None
280 }
281 }
282
283 /// Returns a reference to the inner value as type `dyn T`.
284 ///
285 /// # Examples
286 ///
287 /// ```
288 /// #![feature(downcast_unchecked)]
289 ///
290 /// use std::any::Any;
291 ///
292 /// let x: Box<dyn Any> = Box::new(1_usize);
293 ///
294 /// unsafe {
295 /// assert_eq!(*x.downcast_unchecked_ref::<usize>(), 1);
296 /// }
297 /// ```
298 ///
299 /// # Safety
300 ///
301 /// The contained value must be of type `T`. Calling this method
302 /// with the incorrect type is *undefined behavior*.
303 #[unstable(feature = "downcast_unchecked", issue = "90850")]
304 #[inline]
305 pub unsafe fn downcast_unchecked_ref<T: Any>(&self) -> &T {
306 debug_assert!(self.is::<T>());
307 // SAFETY: caller guarantees that T is the correct type
308 unsafe { &*(self as *const dyn Any as *const T) }
309 }
310
311 /// Returns a mutable reference to the inner value as type `dyn T`.
312 ///
313 /// # Examples
314 ///
315 /// ```
316 /// #![feature(downcast_unchecked)]
317 ///
318 /// use std::any::Any;
319 ///
320 /// let mut x: Box<dyn Any> = Box::new(1_usize);
321 ///
322 /// unsafe {
323 /// *x.downcast_unchecked_mut::<usize>() += 1;
324 /// }
325 ///
326 /// assert_eq!(*x.downcast_ref::<usize>().unwrap(), 2);
327 /// ```
328 ///
329 /// # Safety
330 ///
331 /// The contained value must be of type `T`. Calling this method
332 /// with the incorrect type is *undefined behavior*.
333 #[unstable(feature = "downcast_unchecked", issue = "90850")]
334 #[inline]
335 pub unsafe fn downcast_unchecked_mut<T: Any>(&mut self) -> &mut T {
336 debug_assert!(self.is::<T>());
337 // SAFETY: caller guarantees that T is the correct type
338 unsafe { &mut *(self as *mut dyn Any as *mut T) }
339 }
340}
341
342#[cfg(not(feature = "ferrocene_certified"))]
343impl dyn Any + Send {
344 /// Forwards to the method defined on the type `dyn Any`.
345 ///
346 /// # Examples
347 ///
348 /// ```
349 /// use std::any::Any;
350 ///
351 /// fn is_string(s: &(dyn Any + Send)) {
352 /// if s.is::<String>() {
353 /// println!("It's a string!");
354 /// } else {
355 /// println!("Not a string...");
356 /// }
357 /// }
358 ///
359 /// is_string(&0);
360 /// is_string(&"cookie monster".to_string());
361 /// ```
362 #[stable(feature = "rust1", since = "1.0.0")]
363 #[inline]
364 pub fn is<T: Any>(&self) -> bool {
365 <dyn Any>::is::<T>(self)
366 }
367
368 /// Forwards to the method defined on the type `dyn Any`.
369 ///
370 /// # Examples
371 ///
372 /// ```
373 /// use std::any::Any;
374 ///
375 /// fn print_if_string(s: &(dyn Any + Send)) {
376 /// if let Some(string) = s.downcast_ref::<String>() {
377 /// println!("It's a string({}): '{}'", string.len(), string);
378 /// } else {
379 /// println!("Not a string...");
380 /// }
381 /// }
382 ///
383 /// print_if_string(&0);
384 /// print_if_string(&"cookie monster".to_string());
385 /// ```
386 #[stable(feature = "rust1", since = "1.0.0")]
387 #[inline]
388 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
389 <dyn Any>::downcast_ref::<T>(self)
390 }
391
392 /// Forwards to the method defined on the type `dyn Any`.
393 ///
394 /// # Examples
395 ///
396 /// ```
397 /// use std::any::Any;
398 ///
399 /// fn modify_if_u32(s: &mut (dyn Any + Send)) {
400 /// if let Some(num) = s.downcast_mut::<u32>() {
401 /// *num = 42;
402 /// }
403 /// }
404 ///
405 /// let mut x = 10u32;
406 /// let mut s = "starlord".to_string();
407 ///
408 /// modify_if_u32(&mut x);
409 /// modify_if_u32(&mut s);
410 ///
411 /// assert_eq!(x, 42);
412 /// assert_eq!(&s, "starlord");
413 /// ```
414 #[stable(feature = "rust1", since = "1.0.0")]
415 #[inline]
416 pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
417 <dyn Any>::downcast_mut::<T>(self)
418 }
419
420 /// Forwards to the method defined on the type `dyn Any`.
421 ///
422 /// # Examples
423 ///
424 /// ```
425 /// #![feature(downcast_unchecked)]
426 ///
427 /// use std::any::Any;
428 ///
429 /// let x: Box<dyn Any> = Box::new(1_usize);
430 ///
431 /// unsafe {
432 /// assert_eq!(*x.downcast_unchecked_ref::<usize>(), 1);
433 /// }
434 /// ```
435 ///
436 /// # Safety
437 ///
438 /// The contained value must be of type `T`. Calling this method
439 /// with the incorrect type is *undefined behavior*.
440 #[unstable(feature = "downcast_unchecked", issue = "90850")]
441 #[inline]
442 pub unsafe fn downcast_unchecked_ref<T: Any>(&self) -> &T {
443 // SAFETY: guaranteed by caller
444 unsafe { <dyn Any>::downcast_unchecked_ref::<T>(self) }
445 }
446
447 /// Forwards to the method defined on the type `dyn Any`.
448 ///
449 /// # Examples
450 ///
451 /// ```
452 /// #![feature(downcast_unchecked)]
453 ///
454 /// use std::any::Any;
455 ///
456 /// let mut x: Box<dyn Any> = Box::new(1_usize);
457 ///
458 /// unsafe {
459 /// *x.downcast_unchecked_mut::<usize>() += 1;
460 /// }
461 ///
462 /// assert_eq!(*x.downcast_ref::<usize>().unwrap(), 2);
463 /// ```
464 ///
465 /// # Safety
466 ///
467 /// The contained value must be of type `T`. Calling this method
468 /// with the incorrect type is *undefined behavior*.
469 #[unstable(feature = "downcast_unchecked", issue = "90850")]
470 #[inline]
471 pub unsafe fn downcast_unchecked_mut<T: Any>(&mut self) -> &mut T {
472 // SAFETY: guaranteed by caller
473 unsafe { <dyn Any>::downcast_unchecked_mut::<T>(self) }
474 }
475}
476
477#[cfg(not(feature = "ferrocene_certified"))]
478impl dyn Any + Send + Sync {
479 /// Forwards to the method defined on the type `Any`.
480 ///
481 /// # Examples
482 ///
483 /// ```
484 /// use std::any::Any;
485 ///
486 /// fn is_string(s: &(dyn Any + Send + Sync)) {
487 /// if s.is::<String>() {
488 /// println!("It's a string!");
489 /// } else {
490 /// println!("Not a string...");
491 /// }
492 /// }
493 ///
494 /// is_string(&0);
495 /// is_string(&"cookie monster".to_string());
496 /// ```
497 #[stable(feature = "any_send_sync_methods", since = "1.28.0")]
498 #[inline]
499 pub fn is<T: Any>(&self) -> bool {
500 <dyn Any>::is::<T>(self)
501 }
502
503 /// Forwards to the method defined on the type `Any`.
504 ///
505 /// # Examples
506 ///
507 /// ```
508 /// use std::any::Any;
509 ///
510 /// fn print_if_string(s: &(dyn Any + Send + Sync)) {
511 /// if let Some(string) = s.downcast_ref::<String>() {
512 /// println!("It's a string({}): '{}'", string.len(), string);
513 /// } else {
514 /// println!("Not a string...");
515 /// }
516 /// }
517 ///
518 /// print_if_string(&0);
519 /// print_if_string(&"cookie monster".to_string());
520 /// ```
521 #[stable(feature = "any_send_sync_methods", since = "1.28.0")]
522 #[inline]
523 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
524 <dyn Any>::downcast_ref::<T>(self)
525 }
526
527 /// Forwards to the method defined on the type `Any`.
528 ///
529 /// # Examples
530 ///
531 /// ```
532 /// use std::any::Any;
533 ///
534 /// fn modify_if_u32(s: &mut (dyn Any + Send + Sync)) {
535 /// if let Some(num) = s.downcast_mut::<u32>() {
536 /// *num = 42;
537 /// }
538 /// }
539 ///
540 /// let mut x = 10u32;
541 /// let mut s = "starlord".to_string();
542 ///
543 /// modify_if_u32(&mut x);
544 /// modify_if_u32(&mut s);
545 ///
546 /// assert_eq!(x, 42);
547 /// assert_eq!(&s, "starlord");
548 /// ```
549 #[stable(feature = "any_send_sync_methods", since = "1.28.0")]
550 #[inline]
551 pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
552 <dyn Any>::downcast_mut::<T>(self)
553 }
554
555 /// Forwards to the method defined on the type `Any`.
556 ///
557 /// # Examples
558 ///
559 /// ```
560 /// #![feature(downcast_unchecked)]
561 ///
562 /// use std::any::Any;
563 ///
564 /// let x: Box<dyn Any> = Box::new(1_usize);
565 ///
566 /// unsafe {
567 /// assert_eq!(*x.downcast_unchecked_ref::<usize>(), 1);
568 /// }
569 /// ```
570 /// # Safety
571 ///
572 /// The contained value must be of type `T`. Calling this method
573 /// with the incorrect type is *undefined behavior*.
574 #[unstable(feature = "downcast_unchecked", issue = "90850")]
575 #[inline]
576 pub unsafe fn downcast_unchecked_ref<T: Any>(&self) -> &T {
577 // SAFETY: guaranteed by caller
578 unsafe { <dyn Any>::downcast_unchecked_ref::<T>(self) }
579 }
580
581 /// Forwards to the method defined on the type `Any`.
582 ///
583 /// # Examples
584 ///
585 /// ```
586 /// #![feature(downcast_unchecked)]
587 ///
588 /// use std::any::Any;
589 ///
590 /// let mut x: Box<dyn Any> = Box::new(1_usize);
591 ///
592 /// unsafe {
593 /// *x.downcast_unchecked_mut::<usize>() += 1;
594 /// }
595 ///
596 /// assert_eq!(*x.downcast_ref::<usize>().unwrap(), 2);
597 /// ```
598 /// # Safety
599 ///
600 /// The contained value must be of type `T`. Calling this method
601 /// with the incorrect type is *undefined behavior*.
602 #[unstable(feature = "downcast_unchecked", issue = "90850")]
603 #[inline]
604 pub unsafe fn downcast_unchecked_mut<T: Any>(&mut self) -> &mut T {
605 // SAFETY: guaranteed by caller
606 unsafe { <dyn Any>::downcast_unchecked_mut::<T>(self) }
607 }
608}
609
610///////////////////////////////////////////////////////////////////////////////
611// TypeID and its methods
612///////////////////////////////////////////////////////////////////////////////
613
614/// A `TypeId` represents a globally unique identifier for a type.
615///
616/// Each `TypeId` is an opaque object which does not allow inspection of what's
617/// inside but does allow basic operations such as cloning, comparison,
618/// printing, and showing.
619///
620/// A `TypeId` is currently only available for types which ascribe to `'static`,
621/// but this limitation may be removed in the future.
622///
623/// While `TypeId` implements `Hash`, `PartialOrd`, and `Ord`, it is worth
624/// noting that the hashes and ordering will vary between Rust releases. Beware
625/// of relying on them inside of your code!
626///
627/// # Layout
628///
629/// Like other [`Rust`-representation][repr-rust] types, `TypeId`'s size and layout are unstable.
630/// In particular, this means that you cannot rely on the size and layout of `TypeId` remaining the
631/// same between Rust releases; they are subject to change without prior notice between Rust
632/// releases.
633///
634/// [repr-rust]: https://doc.rust-lang.org/reference/type-layout.html#r-layout.repr.rust.unspecified
635///
636/// # Danger of Improper Variance
637///
638/// You might think that subtyping is impossible between two static types,
639/// but this is false; there exists a static type with a static subtype.
640/// To wit, `fn(&str)`, which is short for `for<'any> fn(&'any str)`, and
641/// `fn(&'static str)`, are two distinct, static types, and yet,
642/// `fn(&str)` is a subtype of `fn(&'static str)`, since any value of type
643/// `fn(&str)` can be used where a value of type `fn(&'static str)` is needed.
644///
645/// This means that abstractions around `TypeId`, despite its
646/// `'static` bound on arguments, still need to worry about unnecessary
647/// and improper variance: it is advisable to strive for invariance
648/// first. The usability impact will be negligible, while the reduction
649/// in the risk of unsoundness will be most welcome.
650///
651/// ## Examples
652///
653/// Suppose `SubType` is a subtype of `SuperType`, that is,
654/// a value of type `SubType` can be used wherever
655/// a value of type `SuperType` is expected.
656/// Suppose also that `CoVar<T>` is a generic type, which is covariant over `T`
657/// (like many other types, including `PhantomData<T>` and `Vec<T>`).
658///
659/// Then, by covariance, `CoVar<SubType>` is a subtype of `CoVar<SuperType>`,
660/// that is, a value of type `CoVar<SubType>` can be used wherever
661/// a value of type `CoVar<SuperType>` is expected.
662///
663/// Then if `CoVar<SuperType>` relies on `TypeId::of::<SuperType>()` to uphold any invariants,
664/// those invariants may be broken because a value of type `CoVar<SuperType>` can be created
665/// without going through any of its methods, like so:
666/// ```
667/// type SubType = fn(&());
668/// type SuperType = fn(&'static ());
669/// type CoVar<T> = Vec<T>; // imagine something more complicated
670///
671/// let sub: CoVar<SubType> = CoVar::new();
672/// // we have a `CoVar<SuperType>` instance without
673/// // *ever* having called `CoVar::<SuperType>::new()`!
674/// let fake_super: CoVar<SuperType> = sub;
675/// ```
676///
677/// The following is an example program that tries to use `TypeId::of` to
678/// implement a generic type `Unique<T>` that guarantees unique instances for each `Unique<T>`,
679/// that is, and for each type `T` there can be at most one value of type `Unique<T>` at any time.
680///
681/// ```
682/// mod unique {
683/// use std::any::TypeId;
684/// use std::collections::BTreeSet;
685/// use std::marker::PhantomData;
686/// use std::sync::Mutex;
687///
688/// static ID_SET: Mutex<BTreeSet<TypeId>> = Mutex::new(BTreeSet::new());
689///
690/// // TypeId has only covariant uses, which makes Unique covariant over TypeAsId 🚨
691/// #[derive(Debug, PartialEq)]
692/// pub struct Unique<TypeAsId: 'static>(
693/// // private field prevents creation without `new` outside this module
694/// PhantomData<TypeAsId>,
695/// );
696///
697/// impl<TypeAsId: 'static> Unique<TypeAsId> {
698/// pub fn new() -> Option<Self> {
699/// let mut set = ID_SET.lock().unwrap();
700/// (set.insert(TypeId::of::<TypeAsId>())).then(|| Self(PhantomData))
701/// }
702/// }
703///
704/// impl<TypeAsId: 'static> Drop for Unique<TypeAsId> {
705/// fn drop(&mut self) {
706/// let mut set = ID_SET.lock().unwrap();
707/// (!set.remove(&TypeId::of::<TypeAsId>())).then(|| panic!("duplicity detected"));
708/// }
709/// }
710/// }
711///
712/// use unique::Unique;
713///
714/// // `OtherRing` is a subtype of `TheOneRing`. Both are 'static, and thus have a TypeId.
715/// type TheOneRing = fn(&'static ());
716/// type OtherRing = fn(&());
717///
718/// fn main() {
719/// let the_one_ring: Unique<TheOneRing> = Unique::new().unwrap();
720/// assert_eq!(Unique::<TheOneRing>::new(), None);
721///
722/// let other_ring: Unique<OtherRing> = Unique::new().unwrap();
723/// // Use that `Unique<OtherRing>` is a subtype of `Unique<TheOneRing>` 🚨
724/// let fake_one_ring: Unique<TheOneRing> = other_ring;
725/// assert_eq!(fake_one_ring, the_one_ring);
726///
727/// std::mem::forget(fake_one_ring);
728/// }
729/// ```
730#[cfg_attr(not(feature = "ferrocene_certified"), derive(Copy, PartialOrd, Ord))]
731#[cfg_attr(not(feature = "ferrocene_certified"), derive_const(Clone, Eq))]
732#[cfg_attr(feature = "ferrocene_certified", derive(Copy))]
733#[cfg_attr(feature = "ferrocene_certified", derive_const(Clone))]
734#[stable(feature = "rust1", since = "1.0.0")]
735#[lang = "type_id"]
736pub struct TypeId {
737 /// This needs to be an array of pointers, since there is provenance
738 /// in the first array field. This provenance knows exactly which type
739 /// the TypeId actually is, allowing CTFE and miri to operate based off it.
740 /// At runtime all the pointers in the array contain bits of the hash, making
741 /// the entire `TypeId` actually just be a `u128` hash of the type.
742 pub(crate) data: [*const (); 16 / size_of::<*const ()>()],
743}
744
745// SAFETY: the raw pointer is always an integer
746#[stable(feature = "rust1", since = "1.0.0")]
747unsafe impl Send for TypeId {}
748// SAFETY: the raw pointer is always an integer
749#[stable(feature = "rust1", since = "1.0.0")]
750unsafe impl Sync for TypeId {}
751
752#[stable(feature = "rust1", since = "1.0.0")]
753#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
754impl const PartialEq for TypeId {
755 #[inline]
756 fn eq(&self, other: &Self) -> bool {
757 #[cfg(miri)]
758 return crate::intrinsics::type_id_eq(*self, *other);
759 #[cfg(not(miri))]
760 {
761 let this = self;
762 crate::intrinsics::const_eval_select!(
763 @capture { this: &TypeId, other: &TypeId } -> bool:
764 if const {
765 crate::intrinsics::type_id_eq(*this, *other)
766 } else {
767 // Ideally we would just invoke `type_id_eq` unconditionally here,
768 // but since we do not MIR inline intrinsics, because backends
769 // may want to override them (and miri does!), MIR opts do not
770 // clean up this call sufficiently for LLVM to turn repeated calls
771 // of `TypeId` comparisons against one specific `TypeId` into
772 // a lookup table.
773 // SAFETY: We know that at runtime none of the bits have provenance and all bits
774 // are initialized. So we can just convert the whole thing to a `u128` and compare that.
775 unsafe {
776 crate::mem::transmute::<_, u128>(*this) == crate::mem::transmute::<_, u128>(*other)
777 }
778 }
779 )
780 }
781 }
782}
783
784impl TypeId {
785 /// Returns the `TypeId` of the generic type parameter.
786 ///
787 /// # Examples
788 ///
789 /// ```
790 /// use std::any::{Any, TypeId};
791 ///
792 /// fn is_string<T: ?Sized + Any>(_s: &T) -> bool {
793 /// TypeId::of::<String>() == TypeId::of::<T>()
794 /// }
795 ///
796 /// assert_eq!(is_string(&0), false);
797 /// assert_eq!(is_string(&"cookie monster".to_string()), true);
798 /// ```
799 #[must_use]
800 #[stable(feature = "rust1", since = "1.0.0")]
801 #[rustc_const_stable(feature = "const_type_id", since = "1.91.0")]
802 pub const fn of<T: ?Sized + 'static>() -> TypeId {
803 const { intrinsics::type_id::<T>() }
804 }
805
806 #[cfg(not(feature = "ferrocene_certified"))]
807 fn as_u128(self) -> u128 {
808 let mut bytes = [0; 16];
809
810 // This is a provenance-stripping memcpy.
811 for (i, chunk) in self.data.iter().copied().enumerate() {
812 let chunk = chunk.addr().to_ne_bytes();
813 let start = i * chunk.len();
814 bytes[start..(start + chunk.len())].copy_from_slice(&chunk);
815 }
816 u128::from_ne_bytes(bytes)
817 }
818}
819
820#[stable(feature = "rust1", since = "1.0.0")]
821#[cfg(not(feature = "ferrocene_certified"))]
822impl hash::Hash for TypeId {
823 #[inline]
824 fn hash<H: hash::Hasher>(&self, state: &mut H) {
825 // We only hash the lower 64 bits of our (128 bit) internal numeric ID,
826 // because:
827 // - The hashing algorithm which backs `TypeId` is expected to be
828 // unbiased and high quality, meaning further mixing would be somewhat
829 // redundant compared to choosing (the lower) 64 bits arbitrarily.
830 // - `Hasher::finish` returns a u64 anyway, so the extra entropy we'd
831 // get from hashing the full value would probably not be useful
832 // (especially given the previous point about the lower 64 bits being
833 // high quality on their own).
834 // - It is correct to do so -- only hashing a subset of `self` is still
835 // compatible with an `Eq` implementation that considers the entire
836 // value, as ours does.
837 let data =
838 // SAFETY: The `offset` stays in-bounds, it just moves the pointer to the 2nd half of the `TypeId`.
839 // Only the first ptr-sized chunk ever has provenance, so that second half is always
840 // fine to read at integer type.
841 unsafe { crate::ptr::read_unaligned(self.data.as_ptr().cast::<u64>().offset(1)) };
842 data.hash(state);
843 }
844}
845
846#[stable(feature = "rust1", since = "1.0.0")]
847#[cfg(not(feature = "ferrocene_certified"))]
848impl fmt::Debug for TypeId {
849 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
850 write!(f, "TypeId({:#034x})", self.as_u128())
851 }
852}
853
854/// Returns the name of a type as a string slice.
855///
856/// # Note
857///
858/// This is intended for diagnostic use. The exact contents and format of the
859/// string returned are not specified, other than being a best-effort
860/// description of the type. For example, amongst the strings
861/// that `type_name::<Option<String>>()` might return are `"Option<String>"` and
862/// `"std::option::Option<std::string::String>"`.
863///
864/// The returned string must not be considered to be a unique identifier of a
865/// type as multiple types may map to the same type name. Similarly, there is no
866/// guarantee that all parts of a type will appear in the returned string. In
867/// addition, the output may change between versions of the compiler. For
868/// example, lifetime specifiers were omitted in some earlier versions.
869///
870/// The current implementation uses the same infrastructure as compiler
871/// diagnostics and debuginfo, but this is not guaranteed.
872///
873/// # Examples
874///
875/// ```rust
876/// assert_eq!(
877/// std::any::type_name::<Option<String>>(),
878/// "core::option::Option<alloc::string::String>",
879/// );
880/// ```
881#[must_use]
882#[stable(feature = "type_name", since = "1.38.0")]
883#[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
884pub const fn type_name<T: ?Sized>() -> &'static str {
885 const { intrinsics::type_name::<T>() }
886}
887
888/// Returns the type name of the pointed-to value as a string slice.
889///
890/// This is the same as `type_name::<T>()`, but can be used where the type of a
891/// variable is not easily available.
892///
893/// # Note
894///
895/// Like [`type_name`], this is intended for diagnostic use and the exact output is not
896/// guaranteed. It provides a best-effort description, but the output may change between
897/// versions of the compiler.
898///
899/// In short: use this for debugging, avoid using the output to affect program behavior. More
900/// information is available at [`type_name`].
901///
902/// Additionally, this function does not resolve trait objects. This means that
903/// `type_name_of_val(&7u32 as &dyn Debug)` may return `"dyn Debug"`, but will not return `"u32"`
904/// at this time.
905///
906/// # Examples
907///
908/// Prints the default integer and float types.
909///
910/// ```rust
911/// use std::any::type_name_of_val;
912///
913/// let s = "foo";
914/// let x: i32 = 1;
915/// let y: f32 = 1.0;
916///
917/// assert!(type_name_of_val(&s).contains("str"));
918/// assert!(type_name_of_val(&x).contains("i32"));
919/// assert!(type_name_of_val(&y).contains("f32"));
920/// ```
921#[must_use]
922#[stable(feature = "type_name_of_val", since = "1.76.0")]
923#[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
924pub const fn type_name_of_val<T: ?Sized>(_val: &T) -> &'static str {
925 type_name::<T>()
926}