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")]
710#[lang = "type_id"]
711pub struct TypeId {
712    /// This needs to be an array of pointers, since there is provenance
713    /// in the first array field. This provenance knows exactly which type
714    /// the TypeId actually is, allowing CTFE and miri to operate based off it.
715    /// At runtime all the pointers in the array contain bits of the hash, making
716    /// the entire `TypeId` actually just be a `u128` hash of the type.
717    pub(crate) data: [*const (); 16 / size_of::<*const ()>()],
718}
719
720// SAFETY: the raw pointer is always an integer
721#[stable(feature = "rust1", since = "1.0.0")]
722unsafe impl Send for TypeId {}
723// SAFETY: the raw pointer is always an integer
724#[stable(feature = "rust1", since = "1.0.0")]
725unsafe impl Sync for TypeId {}
726
727#[stable(feature = "rust1", since = "1.0.0")]
728#[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
729impl const PartialEq for TypeId {
730    #[inline]
731    fn eq(&self, other: &Self) -> bool {
732        #[cfg(miri)]
733        return crate::intrinsics::type_id_eq(*self, *other);
734        #[cfg(not(miri))]
735        {
736            let this = self;
737            crate::intrinsics::const_eval_select!(
738                @capture { this: &TypeId, other: &TypeId } -> bool:
739                if const {
740                    crate::intrinsics::type_id_eq(*this, *other)
741                } else {
742                    // Ideally we would just invoke `type_id_eq` unconditionally here,
743                    // but since we do not MIR inline intrinsics, because backends
744                    // may want to override them (and miri does!), MIR opts do not
745                    // clean up this call sufficiently for LLVM to turn repeated calls
746                    // of `TypeId` comparisons against one specific `TypeId` into
747                    // a lookup table.
748                    // SAFETY: We know that at runtime none of the bits have provenance and all bits
749                    // are initialized. So we can just convert the whole thing to a `u128` and compare that.
750                    unsafe {
751                        crate::mem::transmute::<_, u128>(*this) == crate::mem::transmute::<_, u128>(*other)
752                    }
753                }
754            )
755        }
756    }
757}
758
759impl TypeId {
760    /// Returns the `TypeId` of the generic type parameter.
761    ///
762    /// # Examples
763    ///
764    /// ```
765    /// use std::any::{Any, TypeId};
766    ///
767    /// fn is_string<T: ?Sized + Any>(_s: &T) -> bool {
768    ///     TypeId::of::<String>() == TypeId::of::<T>()
769    /// }
770    ///
771    /// assert_eq!(is_string(&0), false);
772    /// assert_eq!(is_string(&"cookie monster".to_string()), true);
773    /// ```
774    #[must_use]
775    #[stable(feature = "rust1", since = "1.0.0")]
776    #[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
777    pub const fn of<T: ?Sized + 'static>() -> TypeId {
778        const { intrinsics::type_id::<T>() }
779    }
780
781    fn as_u128(self) -> u128 {
782        let mut bytes = [0; 16];
783
784        // This is a provenance-stripping memcpy.
785        for (i, chunk) in self.data.iter().copied().enumerate() {
786            let chunk = chunk.addr().to_ne_bytes();
787            let start = i * chunk.len();
788            bytes[start..(start + chunk.len())].copy_from_slice(&chunk);
789        }
790        u128::from_ne_bytes(bytes)
791    }
792}
793
794#[stable(feature = "rust1", since = "1.0.0")]
795impl hash::Hash for TypeId {
796    #[inline]
797    fn hash<H: hash::Hasher>(&self, state: &mut H) {
798        // We only hash the lower 64 bits of our (128 bit) internal numeric ID,
799        // because:
800        // - The hashing algorithm which backs `TypeId` is expected to be
801        //   unbiased and high quality, meaning further mixing would be somewhat
802        //   redundant compared to choosing (the lower) 64 bits arbitrarily.
803        // - `Hasher::finish` returns a u64 anyway, so the extra entropy we'd
804        //   get from hashing the full value would probably not be useful
805        //   (especially given the previous point about the lower 64 bits being
806        //   high quality on their own).
807        // - It is correct to do so -- only hashing a subset of `self` is still
808        //   compatible with an `Eq` implementation that considers the entire
809        //   value, as ours does.
810        let data =
811        // SAFETY: The `offset` stays in-bounds, it just moves the pointer to the 2nd half of the `TypeId`.
812        // Only the first ptr-sized chunk ever has provenance, so that second half is always
813        // fine to read at integer type.
814            unsafe { crate::ptr::read_unaligned(self.data.as_ptr().cast::<u64>().offset(1)) };
815        data.hash(state);
816    }
817}
818
819#[stable(feature = "rust1", since = "1.0.0")]
820impl fmt::Debug for TypeId {
821    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
822        write!(f, "TypeId({:#034x})", self.as_u128())
823    }
824}
825
826/// Returns the name of a type as a string slice.
827///
828/// # Note
829///
830/// This is intended for diagnostic use. The exact contents and format of the
831/// string returned are not specified, other than being a best-effort
832/// description of the type. For example, amongst the strings
833/// that `type_name::<Option<String>>()` might return are `"Option<String>"` and
834/// `"std::option::Option<std::string::String>"`.
835///
836/// The returned string must not be considered to be a unique identifier of a
837/// type as multiple types may map to the same type name. Similarly, there is no
838/// guarantee that all parts of a type will appear in the returned string: for
839/// example, lifetime specifiers are currently not included. In addition, the
840/// output may change between versions of the compiler.
841///
842/// The current implementation uses the same infrastructure as compiler
843/// diagnostics and debuginfo, but this is not guaranteed.
844///
845/// # Examples
846///
847/// ```rust
848/// assert_eq!(
849///     std::any::type_name::<Option<String>>(),
850///     "core::option::Option<alloc::string::String>",
851/// );
852/// ```
853#[must_use]
854#[stable(feature = "type_name", since = "1.38.0")]
855#[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
856pub const fn type_name<T: ?Sized>() -> &'static str {
857    const { intrinsics::type_name::<T>() }
858}
859
860/// Returns the type name of the pointed-to value as a string slice.
861///
862/// This is the same as `type_name::<T>()`, but can be used where the type of a
863/// variable is not easily available.
864///
865/// # Note
866///
867/// Like [`type_name`], this is intended for diagnostic use and the exact output is not
868/// guaranteed. It provides a best-effort description, but the output may change between
869/// versions of the compiler.
870///
871/// In short: use this for debugging, avoid using the output to affect program behavior. More
872/// information is available at [`type_name`].
873///
874/// Additionally, this function does not resolve trait objects. This means that
875/// `type_name_of_val(&7u32 as &dyn Debug)` may return `"dyn Debug"`, but will not return `"u32"`
876/// at this time.
877///
878/// # Examples
879///
880/// Prints the default integer and float types.
881///
882/// ```rust
883/// use std::any::type_name_of_val;
884///
885/// let s = "foo";
886/// let x: i32 = 1;
887/// let y: f32 = 1.0;
888///
889/// assert!(type_name_of_val(&s).contains("str"));
890/// assert!(type_name_of_val(&x).contains("i32"));
891/// assert!(type_name_of_val(&y).contains("f32"));
892/// ```
893#[must_use]
894#[stable(feature = "type_name_of_val", since = "1.76.0")]
895#[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
896pub const fn type_name_of_val<T: ?Sized>(_val: &T) -> &'static str {
897    type_name::<T>()
898}
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