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

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy