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 used6//! 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`, there9//! is also the `downcast_mut` method, for getting a mutable reference to the10//! inner value. `Box<dyn Any>` adds the `downcast` method, which attempts to11//! 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 specified14//! concrete type, and cannot be used to test whether a type implements a trait.15//!16//! [`Box`]: ../../std/boxed/struct.Box.html17//!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 simply22//! calling `.type_id()` on the value will produce the `TypeId` of the23//! *container*, not the underlying trait object. This can be avoided by24//! converting the smart pointer into a `&dyn Any` instead, which will return25//! 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//! ## Examples42//!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 its45//! concrete type. We want to give special treatment to certain types: in this46//! 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 to48//! use runtime reflection instead.49//!50//! ```rust51//! 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 to59//! // output the `String`'s length as well as its value. If not, it's a60//! // 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 work75//! }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//!8687#![stable(feature ="rust1", since ="1.0.0")]8889use crate::{fmt, hash, intrinsics};9091///////////////////////////////////////////////////////////////////////////////92// Any trait93///////////////////////////////////////////////////////////////////////////////9495/// 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::any101// This trait is not unsafe, though we rely on the specifics of it's sole impl's102// `type_id` function in unsafe code (e.g., `downcast`). Normally, that would be103// a problem, but because the only impl of `Any` is a blanket implementation, no104// 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's108// both not really necessary and may confuse users about the distinction of109// 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 traitAny:'static{114/// Gets the `TypeId` of `self`.115 ///116 /// If called on a `dyn Any` trait object117 /// (or a trait object of a subtrait of `Any`),118 /// this returns the `TypeId` of the underlying119 /// concrete type, not that of `dyn Any` itself.120 ///121 /// # Examples122 ///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")]134fntype_id(&self) -> TypeId;135}136137#[stable(feature ="rust1", since ="1.0.0")]138impl<T:'static+?Sized> AnyforT {139fntype_id(&self) -> TypeId {140 TypeId::of::<T>()141 }142}143144///////////////////////////////////////////////////////////////////////////////145// Extension methods for Any trait objects.146///////////////////////////////////////////////////////////////////////////////147148#[stable(feature ="rust1", since ="1.0.0")]149implfmt::Debugfor dynAny {150fnfmt(&self, f:&mutfmt::Formatter<'_>) -> fmt::Result {151 f.debug_struct("Any").finish_non_exhaustive()152 }153}154155// Ensure that the result of e.g., joining a thread can be printed and156// hence used with `unwrap`. May eventually no longer be needed if157// dispatch works with upcasting.158#[stable(feature ="rust1", since ="1.0.0")]159implfmt::Debugfor dynAny + Send {160fnfmt(&self, f:&mutfmt::Formatter<'_>) -> fmt::Result {161 f.debug_struct("Any").finish_non_exhaustive()162 }163}164165#[stable(feature ="any_send_sync_methods", since ="1.28.0")]166implfmt::Debugfor dynAny + Send + Sync {167fnfmt(&self, f:&mutfmt::Formatter<'_>) -> fmt::Result {168 f.debug_struct("Any").finish_non_exhaustive()169 }170}171172impl dynAny {173/// Returns `true` if the inner type is the same as `T`.174 ///175 /// # Examples176 ///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]193pub fnis<T: Any>(&self) -> bool {194// Get `TypeId` of the type this function is instantiated with.195lett = TypeId::of::<T>();196197// Get `TypeId` of the type in the trait object (`self`).198letconcrete =self.type_id();199200// Compare both `TypeId`s on equality.201t == concrete202 }203204/// Returns some reference to the inner value if it is of type `T`, or205 /// `None` if it isn't.206 ///207 /// # Examples208 ///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]225pub fndowncast_ref<T: Any>(&self) ->Option<&T> {226ifself.is::<T>() {227// SAFETY: just checked whether we are pointing to the correct type, and we can rely on228 // that check for memory safety because we have implemented Any for all types; no other229 // impls can exist as they would conflict with our impl.230unsafe{Some(self.downcast_ref_unchecked()) }231 }else{232None233}234 }235236/// Returns some mutable reference to the inner value if it is of type `T`, or237 /// `None` if it isn't.238 ///239 /// # Examples240 ///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]261pub fndowncast_mut<T: Any>(&mutself) ->Option<&mutT> {262ifself.is::<T>() {263// SAFETY: just checked whether we are pointing to the correct type, and we can rely on264 // that check for memory safety because we have implemented Any for all types; no other265 // impls can exist as they would conflict with our impl.266unsafe{Some(self.downcast_mut_unchecked()) }267 }else{268None269}270 }271272/// Returns a reference to the inner value as type `dyn T`.273 ///274 /// # Examples275 ///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 /// # Safety289 ///290 /// The contained value must be of type `T`. Calling this method291 /// with the incorrect type is *undefined behavior*.292#[unstable(feature ="downcast_unchecked", issue ="90850")]293 #[inline]294pub unsafe fndowncast_ref_unchecked<T: Any>(&self) ->&T {295debug_assert!(self.is::<T>());296// SAFETY: caller guarantees that T is the correct type297unsafe{&*(selfas*constdynAnyas*constT) }298 }299300/// Returns a mutable reference to the inner value as type `dyn T`.301 ///302 /// # Examples303 ///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 /// # Safety319 ///320 /// The contained value must be of type `T`. Calling this method321 /// with the incorrect type is *undefined behavior*.322#[unstable(feature ="downcast_unchecked", issue ="90850")]323 #[inline]324pub unsafe fndowncast_mut_unchecked<T: Any>(&mutself) ->&mutT {325debug_assert!(self.is::<T>());326// SAFETY: caller guarantees that T is the correct type327unsafe{&mut *(selfas*mutdynAnyas*mutT) }328 }329}330331impl dynAny + Send {332/// Forwards to the method defined on the type `dyn Any`.333 ///334 /// # Examples335 ///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]352pub fnis<T: Any>(&self) -> bool {353 <dynAny>::is::<T>(self)354 }355356/// Forwards to the method defined on the type `dyn Any`.357 ///358 /// # Examples359 ///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]376pub fndowncast_ref<T: Any>(&self) ->Option<&T> {377 <dynAny>::downcast_ref::<T>(self)378 }379380/// Forwards to the method defined on the type `dyn Any`.381 ///382 /// # Examples383 ///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]404pub fndowncast_mut<T: Any>(&mutself) ->Option<&mutT> {405 <dynAny>::downcast_mut::<T>(self)406 }407408/// Forwards to the method defined on the type `dyn Any`.409 ///410 /// # Examples411 ///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 /// # Safety425 ///426 /// The contained value must be of type `T`. Calling this method427 /// with the incorrect type is *undefined behavior*.428#[unstable(feature ="downcast_unchecked", issue ="90850")]429 #[inline]430pub unsafe fndowncast_ref_unchecked<T: Any>(&self) ->&T {431// SAFETY: guaranteed by caller432unsafe{ <dynAny>::downcast_ref_unchecked::<T>(self) }433 }434435/// Forwards to the method defined on the type `dyn Any`.436 ///437 /// # Examples438 ///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 /// # Safety454 ///455 /// The contained value must be of type `T`. Calling this method456 /// with the incorrect type is *undefined behavior*.457#[unstable(feature ="downcast_unchecked", issue ="90850")]458 #[inline]459pub unsafe fndowncast_mut_unchecked<T: Any>(&mutself) ->&mutT {460// SAFETY: guaranteed by caller461unsafe{ <dynAny>::downcast_mut_unchecked::<T>(self) }462 }463}464465impl dynAny + Send + Sync {466/// Forwards to the method defined on the type `Any`.467 ///468 /// # Examples469 ///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]486pub fnis<T: Any>(&self) -> bool {487 <dynAny>::is::<T>(self)488 }489490/// Forwards to the method defined on the type `Any`.491 ///492 /// # Examples493 ///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]510pub fndowncast_ref<T: Any>(&self) ->Option<&T> {511 <dynAny>::downcast_ref::<T>(self)512 }513514/// Forwards to the method defined on the type `Any`.515 ///516 /// # Examples517 ///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]538pub fndowncast_mut<T: Any>(&mutself) ->Option<&mutT> {539 <dynAny>::downcast_mut::<T>(self)540 }541542/// Forwards to the method defined on the type `Any`.543 ///544 /// # Examples545 ///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 /// # Safety558 ///559 /// The contained value must be of type `T`. Calling this method560 /// with the incorrect type is *undefined behavior*.561#[unstable(feature ="downcast_unchecked", issue ="90850")]562 #[inline]563pub unsafe fndowncast_ref_unchecked<T: Any>(&self) ->&T {564// SAFETY: guaranteed by caller565unsafe{ <dynAny>::downcast_ref_unchecked::<T>(self) }566 }567568/// Forwards to the method defined on the type `Any`.569 ///570 /// # Examples571 ///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 /// # Safety586 ///587 /// The contained value must be of type `T`. Calling this method588 /// with the incorrect type is *undefined behavior*.589#[unstable(feature ="downcast_unchecked", issue ="90850")]590 #[inline]591pub unsafe fndowncast_mut_unchecked<T: Any>(&mutself) ->&mutT {592// SAFETY: guaranteed by caller593unsafe{ <dynAny>::downcast_mut_unchecked::<T>(self) }594 }595}596597///////////////////////////////////////////////////////////////////////////////598// TypeID and its methods599///////////////////////////////////////////////////////////////////////////////600601/// 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's604/// 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 worth611/// noting that the hashes and ordering will vary between Rust releases. Beware612/// of relying on them inside of your code!613///614/// # Danger of Improper Variance615///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)`, and619/// `fn(&'static str)`, are two distinct, static types, and yet,620/// `fn(&str)` is a subtype of `fn(&'static str)`, since any value of type621/// `fn(&str)` can be used where a value of type `fn(&'static str)` is needed.622///623/// This means that abstractions around `TypeId`, despite its624/// `'static` bound on arguments, still need to worry about unnecessary625/// and improper variance: it is advisable to strive for invariance626/// first. The usability impact will be negligible, while the reduction627/// in the risk of unsoundness will be most welcome.628///629/// ## Examples630///631/// Suppose `SubType` is a subtype of `SuperType`, that is,632/// a value of type `SubType` can be used wherever633/// 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 wherever639/// 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 created643/// 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 complicated648///649/// let sub: CoVar<SubType> = CoVar::new();650/// // we have a `CoVar<SuperType>` instance without651/// // *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` to656/// 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 module672/// 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 structTypeId {712/// This needs to be an array of pointers, since there is provenance713 /// in the first array field. This provenance knows exactly which type714 /// 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, making716 /// the entire `TypeId` actually just be a `u128` hash of the type.717pub(crate) data: [*const();16/ size_of::<*const()>()],718}719720// SAFETY: the raw pointer is always an integer721#[stable(feature ="rust1", since ="1.0.0")]722unsafe implSendforTypeId {}723// SAFETY: the raw pointer is always an integer724#[stable(feature ="rust1", since ="1.0.0")]725unsafe implSyncforTypeId {}726727#[stable(feature ="rust1", since ="1.0.0")]728#[rustc_const_unstable(feature ="const_type_id", issue ="77125")]729impl constPartialEqforTypeId {730#[inline]731fneq(&self, other:&Self) -> bool {732#[cfg(miri)]733returncrate::intrinsics::type_id_eq(*self,*other);734#[cfg(not(miri))]735{736letthis =self;737crate::intrinsics::const_eval_select!(738 @capture { this:&TypeId, other:&TypeId } -> bool:739if const{740crate::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 backends744 // may want to override them (and miri does!), MIR opts do not745 // clean up this call sufficiently for LLVM to turn repeated calls746 // of `TypeId` comparisons against one specific `TypeId` into747 // a lookup table.748 // SAFETY: We know that at runtime none of the bits have provenance and all bits749 // are initialized. So we can just convert the whole thing to a `u128` and compare that.750unsafe{751crate::mem::transmute::<_, u128>(*this) ==crate::mem::transmute::<_, u128>(*other)752 }753 }754 )755 }756 }757}758759implTypeId {760/// Returns the `TypeId` of the generic type parameter.761 ///762 /// # Examples763 ///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")]777pub const fnof<T:?Sized +'static>() -> TypeId {778const{ intrinsics::type_id::<T>() }779 }780781fnas_u128(self) -> u128 {782letmutbytes = [0;16];783784// This is a provenance-stripping memcpy.785for(i, chunk)inself.data.iter().copied().enumerate() {786letchunk = chunk.expose_provenance().to_ne_bytes();787letstart = i * chunk.len();788 bytes[start..(start + chunk.len())].copy_from_slice(&chunk);789 }790 u128::from_ne_bytes(bytes)791 }792}793794#[stable(feature ="rust1", since ="1.0.0")]795implhash::HashforTypeId {796#[inline]797fnhash<H: hash::Hasher>(&self, state:&mutH) {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 be801 // unbiased and high quality, meaning further mixing would be somewhat802 // redundant compared to choosing (the lower) 64 bits arbitrarily.803 // - `Hasher::finish` returns a u64 anyway, so the extra entropy we'd804 // get from hashing the full value would probably not be useful805 // (especially given the previous point about the lower 64 bits being806 // high quality on their own).807 // - It is correct to do so -- only hashing a subset of `self` is still808 // compatible with an `Eq` implementation that considers the entire809 // value, as ours does.810letdata =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 always813 // fine to read at integer type.814unsafe{crate::ptr::read_unaligned(self.data.as_ptr().cast::<u64>().offset(1)) };815 data.hash(state);816 }817}818819#[stable(feature ="rust1", since ="1.0.0")]820implfmt::DebugforTypeId {821fnfmt(&self, f:&mutfmt::Formatter<'_>) ->Result<(), fmt::Error> {822write!(f,"TypeId({:#034x})",self.as_u128())823 }824}825826/// Returns the name of a type as a string slice.827///828/// # Note829///830/// This is intended for diagnostic use. The exact contents and format of the831/// string returned are not specified, other than being a best-effort832/// description of the type. For example, amongst the strings833/// that `type_name::<Option<String>>()` might return are `"Option<String>"` and834/// `"std::option::Option<std::string::String>"`.835///836/// The returned string must not be considered to be a unique identifier of a837/// type as multiple types may map to the same type name. Similarly, there is no838/// guarantee that all parts of a type will appear in the returned string: for839/// example, lifetime specifiers are currently not included. In addition, the840/// output may change between versions of the compiler.841///842/// The current implementation uses the same infrastructure as compiler843/// diagnostics and debuginfo, but this is not guaranteed.844///845/// # Examples846///847/// ```rust848/// 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 fntype_name<T:?Sized>() ->&'staticstr {857const{ intrinsics::type_name::<T>() }858}859860/// 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 a863/// variable is not easily available.864///865/// # Note866///867/// Like [`type_name`], this is intended for diagnostic use and the exact output is not868/// guaranteed. It provides a best-effort description, but the output may change between869/// versions of the compiler.870///871/// In short: use this for debugging, avoid using the output to affect program behavior. More872/// information is available at [`type_name`].873///874/// Additionally, this function does not resolve trait objects. This means that875/// `type_name_of_val(&7u32 as &dyn Debug)` may return `"dyn Debug"`, but will not return `"u32"`876/// at this time.877///878/// # Examples879///880/// Prints the default integer and float types.881///882/// ```rust883/// 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 fntype_name_of_val<T:?Sized>(_val:&T) ->&'staticstr {897 type_name::<T>()898}