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#[cfg_attr(not(test), 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}