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")]8889usecrate::{fmt, hash, intrinsics, ptr};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_unchecked_ref()) }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_unchecked_mut()) }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_unchecked_ref::<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_unchecked_ref<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_unchecked_mut::<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_unchecked_mut<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_unchecked_ref::<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_unchecked_ref<T: Any>(&self) ->&T {431// SAFETY: guaranteed by caller432unsafe{ <dynAny>::downcast_unchecked_ref::<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_unchecked_mut::<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_unchecked_mut<T: Any>(&mutself) ->&mutT {460// SAFETY: guaranteed by caller461unsafe{ <dynAny>::downcast_unchecked_mut::<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_unchecked_ref::<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_unchecked_ref<T: Any>(&self) ->&T {564// SAFETY: guaranteed by caller565unsafe{ <dynAny>::downcast_unchecked_ref::<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_unchecked_mut::<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_unchecked_mut<T: Any>(&mutself) ->&mutT {592// SAFETY: guaranteed by caller593unsafe{ <dynAny>::downcast_unchecked_mut::<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/// # Layout615///616/// Like other [`Rust`-representation][repr-rust] types, `TypeId`'s size and layout are unstable.617/// In particular, this means that you cannot rely on the size and layout of `TypeId` remaining the618/// same between Rust releases; they are subject to change without prior notice between Rust619/// releases.620///621/// [repr-rust]: https://doc.rust-lang.org/reference/type-layout.html#r-layout.repr.rust.unspecified622///623/// # Danger of Improper Variance624///625/// You might think that subtyping is impossible between two static types,626/// but this is false; there exists a static type with a static subtype.627/// To wit, `fn(&str)`, which is short for `for<'any> fn(&'any str)`, and628/// `fn(&'static str)`, are two distinct, static types, and yet,629/// `fn(&str)` is a subtype of `fn(&'static str)`, since any value of type630/// `fn(&str)` can be used where a value of type `fn(&'static str)` is needed.631///632/// This means that abstractions around `TypeId`, despite its633/// `'static` bound on arguments, still need to worry about unnecessary634/// and improper variance: it is advisable to strive for invariance635/// first. The usability impact will be negligible, while the reduction636/// in the risk of unsoundness will be most welcome.637///638/// ## Examples639///640/// Suppose `SubType` is a subtype of `SuperType`, that is,641/// a value of type `SubType` can be used wherever642/// a value of type `SuperType` is expected.643/// Suppose also that `CoVar<T>` is a generic type, which is covariant over `T`644/// (like many other types, including `PhantomData<T>` and `Vec<T>`).645///646/// Then, by covariance, `CoVar<SubType>` is a subtype of `CoVar<SuperType>`,647/// that is, a value of type `CoVar<SubType>` can be used wherever648/// a value of type `CoVar<SuperType>` is expected.649///650/// Then if `CoVar<SuperType>` relies on `TypeId::of::<SuperType>()` to uphold any invariants,651/// those invariants may be broken because a value of type `CoVar<SuperType>` can be created652/// without going through any of its methods, like so:653/// ```654/// type SubType = fn(&());655/// type SuperType = fn(&'static ());656/// type CoVar<T> = Vec<T>; // imagine something more complicated657///658/// let sub: CoVar<SubType> = CoVar::new();659/// // we have a `CoVar<SuperType>` instance without660/// // *ever* having called `CoVar::<SuperType>::new()`!661/// let fake_super: CoVar<SuperType> = sub;662/// ```663///664/// The following is an example program that tries to use `TypeId::of` to665/// implement a generic type `Unique<T>` that guarantees unique instances for each `Unique<T>`,666/// that is, and for each type `T` there can be at most one value of type `Unique<T>` at any time.667///668/// ```669/// mod unique {670/// use std::any::TypeId;671/// use std::collections::BTreeSet;672/// use std::marker::PhantomData;673/// use std::sync::Mutex;674///675/// static ID_SET: Mutex<BTreeSet<TypeId>> = Mutex::new(BTreeSet::new());676///677/// // TypeId has only covariant uses, which makes Unique covariant over TypeAsId 🚨678/// #[derive(Debug, PartialEq)]679/// pub struct Unique<TypeAsId: 'static>(680/// // private field prevents creation without `new` outside this module681/// PhantomData<TypeAsId>,682/// );683///684/// impl<TypeAsId: 'static> Unique<TypeAsId> {685/// pub fn new() -> Option<Self> {686/// let mut set = ID_SET.lock().unwrap();687/// (set.insert(TypeId::of::<TypeAsId>())).then(|| Self(PhantomData))688/// }689/// }690///691/// impl<TypeAsId: 'static> Drop for Unique<TypeAsId> {692/// fn drop(&mut self) {693/// let mut set = ID_SET.lock().unwrap();694/// (!set.remove(&TypeId::of::<TypeAsId>())).then(|| panic!("duplicity detected"));695/// }696/// }697/// }698///699/// use unique::Unique;700///701/// // `OtherRing` is a subtype of `TheOneRing`. Both are 'static, and thus have a TypeId.702/// type TheOneRing = fn(&'static ());703/// type OtherRing = fn(&());704///705/// fn main() {706/// let the_one_ring: Unique<TheOneRing> = Unique::new().unwrap();707/// assert_eq!(Unique::<TheOneRing>::new(), None);708///709/// let other_ring: Unique<OtherRing> = Unique::new().unwrap();710/// // Use that `Unique<OtherRing>` is a subtype of `Unique<TheOneRing>` 🚨711/// let fake_one_ring: Unique<TheOneRing> = other_ring;712/// assert_eq!(fake_one_ring, the_one_ring);713///714/// std::mem::forget(fake_one_ring);715/// }716/// ```717#[derive(Copy, PartialOrd, Ord)]718#[derive_const(Clone, Eq)]719#[stable(feature ="rust1", since ="1.0.0")]720#[lang ="type_id"]721pub structTypeId {722/// This needs to be an array of pointers, since there is provenance723 /// in the first array field. This provenance knows exactly which type724 /// the TypeId actually is, allowing CTFE and miri to operate based off it.725 /// At runtime all the pointers in the array contain bits of the hash, making726 /// the entire `TypeId` actually just be a `u128` hash of the type.727pub(crate) data: [*const();16/ size_of::<*const()>()],728}729730// SAFETY: the raw pointer is always an integer731#[stable(feature ="rust1", since ="1.0.0")]732unsafe implSendforTypeId {}733// SAFETY: the raw pointer is always an integer734#[stable(feature ="rust1", since ="1.0.0")]735unsafe implSyncforTypeId {}736737#[stable(feature ="rust1", since ="1.0.0")]738#[rustc_const_unstable(feature ="const_cmp", issue ="143800")]739impl constPartialEqforTypeId {740#[inline]741fneq(&self, other:&Self) -> bool {742#[cfg(miri)]743returncrate::intrinsics::type_id_eq(*self,*other);744#[cfg(not(miri))]745{746letthis =self;747crate::intrinsics::const_eval_select!(748 @capture { this:&TypeId, other:&TypeId } -> bool:749if const{750crate::intrinsics::type_id_eq(*this,*other)751 }else{752// Ideally we would just invoke `type_id_eq` unconditionally here,753 // but since we do not MIR inline intrinsics, because backends754 // may want to override them (and miri does!), MIR opts do not755 // clean up this call sufficiently for LLVM to turn repeated calls756 // of `TypeId` comparisons against one specific `TypeId` into757 // a lookup table.758 // SAFETY: We know that at runtime none of the bits have provenance and all bits759 // are initialized. So we can just convert the whole thing to a `u128` and compare that.760unsafe{761crate::mem::transmute::<_, u128>(*this) ==crate::mem::transmute::<_, u128>(*other)762 }763 }764 )765 }766 }767}768769implTypeId {770/// Returns the `TypeId` of the generic type parameter.771 ///772 /// # Examples773 ///774 /// ```775 /// use std::any::{Any, TypeId};776 ///777 /// fn is_string<T: ?Sized + Any>(_s: &T) -> bool {778 /// TypeId::of::<String>() == TypeId::of::<T>()779 /// }780 ///781 /// assert_eq!(is_string(&0), false);782 /// assert_eq!(is_string(&"cookie monster".to_string()), true);783 /// ```784#[must_use]785 #[stable(feature ="rust1", since ="1.0.0")]786 #[rustc_const_stable(feature ="const_type_id", since ="1.91.0")]787pub const fnof<T:?Sized +'static>() -> TypeId {788const{ intrinsics::type_id::<T>() }789 }790791fnas_u128(self) -> u128 {792letmutbytes = [0;16];793794// This is a provenance-stripping memcpy.795for(i, chunk)inself.data.iter().copied().enumerate() {796letchunk = chunk.addr().to_ne_bytes();797letstart = i * chunk.len();798 bytes[start..(start + chunk.len())].copy_from_slice(&chunk);799 }800 u128::from_ne_bytes(bytes)801 }802}803804#[stable(feature ="rust1", since ="1.0.0")]805implhash::HashforTypeId {806#[inline]807fnhash<H: hash::Hasher>(&self, state:&mutH) {808// We only hash the lower 64 bits of our (128 bit) internal numeric ID,809 // because:810 // - The hashing algorithm which backs `TypeId` is expected to be811 // unbiased and high quality, meaning further mixing would be somewhat812 // redundant compared to choosing (the lower) 64 bits arbitrarily.813 // - `Hasher::finish` returns a u64 anyway, so the extra entropy we'd814 // get from hashing the full value would probably not be useful815 // (especially given the previous point about the lower 64 bits being816 // high quality on their own).817 // - It is correct to do so -- only hashing a subset of `self` is still818 // compatible with an `Eq` implementation that considers the entire819 // value, as ours does.820letdata =821// SAFETY: The `offset` stays in-bounds, it just moves the pointer to the 2nd half of the `TypeId`.822 // Only the first ptr-sized chunk ever has provenance, so that second half is always823 // fine to read at integer type.824unsafe{crate::ptr::read_unaligned(self.data.as_ptr().cast::<u64>().offset(1)) };825 data.hash(state);826 }827}828829#[stable(feature ="rust1", since ="1.0.0")]830implfmt::DebugforTypeId {831fnfmt(&self, f:&mutfmt::Formatter<'_>) ->Result<(), fmt::Error> {832write!(f,"TypeId({:#034x})",self.as_u128())833 }834}835836/// Returns the name of a type as a string slice.837///838/// # Note839///840/// This is intended for diagnostic use. The exact contents and format of the841/// string returned are not specified, other than being a best-effort842/// description of the type. For example, amongst the strings843/// that `type_name::<Option<String>>()` might return are `"Option<String>"` and844/// `"std::option::Option<std::string::String>"`.845///846/// The returned string must not be considered to be a unique identifier of a847/// type as multiple types may map to the same type name. Similarly, there is no848/// guarantee that all parts of a type will appear in the returned string. In849/// addition, the output may change between versions of the compiler. For850/// example, lifetime specifiers were omitted in some earlier versions.851///852/// The current implementation uses the same infrastructure as compiler853/// diagnostics and debuginfo, but this is not guaranteed.854///855/// # Examples856///857/// ```rust858/// assert_eq!(859/// std::any::type_name::<Option<String>>(),860/// "core::option::Option<alloc::string::String>",861/// );862/// ```863#[must_use]864#[stable(feature ="type_name", since ="1.38.0")]865#[rustc_const_unstable(feature ="const_type_name", issue ="63084")]866pub const fntype_name<T:?Sized>() ->&'staticstr {867const{ intrinsics::type_name::<T>() }868}869870/// Returns the type name of the pointed-to value as a string slice.871///872/// This is the same as `type_name::<T>()`, but can be used where the type of a873/// variable is not easily available.874///875/// # Note876///877/// Like [`type_name`], this is intended for diagnostic use and the exact output is not878/// guaranteed. It provides a best-effort description, but the output may change between879/// versions of the compiler.880///881/// In short: use this for debugging, avoid using the output to affect program behavior. More882/// information is available at [`type_name`].883///884/// Additionally, this function does not resolve trait objects. This means that885/// `type_name_of_val(&7u32 as &dyn Debug)` may return `"dyn Debug"`, but will not return `"u32"`886/// at this time.887///888/// # Examples889///890/// Prints the default integer and float types.891///892/// ```rust893/// use std::any::type_name_of_val;894///895/// let s = "foo";896/// let x: i32 = 1;897/// let y: f32 = 1.0;898///899/// assert!(type_name_of_val(&s).contains("str"));900/// assert!(type_name_of_val(&x).contains("i32"));901/// assert!(type_name_of_val(&y).contains("f32"));902/// ```903#[must_use]904#[stable(feature ="type_name_of_val", since ="1.76.0")]905#[rustc_const_unstable(feature ="const_type_name", issue ="63084")]906pub const fntype_name_of_val<T:?Sized>(_val:&T) ->&'staticstr {907 type_name::<T>()908}909910/// Returns `Some(&U)` if `T` can be coerced to the trait object type `U`. Otherwise, it returns `None`.911///912/// # Compile-time failures913/// Determining whether `T` can be coerced to the trait object type `U` requires compiler trait resolution.914/// In some cases, that resolution can exceed the recursion limit,915/// and compilation will fail instead of this function returning `None`.916/// # Examples917///918/// ```rust919/// #![feature(try_as_dyn)]920///921/// use core::any::try_as_dyn;922///923/// trait Animal {924/// fn speak(&self) -> &'static str;925/// }926///927/// struct Dog;928/// impl Animal for Dog {929/// fn speak(&self) -> &'static str { "woof" }930/// }931///932/// struct Rock; // does not implement Animal933///934/// let dog = Dog;935/// let rock = Rock;936///937/// let as_animal: Option<&dyn Animal> = try_as_dyn::<Dog, dyn Animal>(&dog);938/// assert_eq!(as_animal.unwrap().speak(), "woof");939///940/// let not_an_animal: Option<&dyn Animal> = try_as_dyn::<Rock, dyn Animal>(&rock);941/// assert!(not_an_animal.is_none());942/// ```943#[must_use]944#[unstable(feature ="try_as_dyn", issue ="144361")]945pub const fntry_as_dyn<946 T: Any +'static,947 U: ptr::Pointee<Metadata = ptr::DynMetadata<U>> +?Sized +'static,948>(949 t:&T,950) ->Option<&U> {951letvtable:Option<ptr::DynMetadata<U>> =const{ intrinsics::vtable_for::<T, U>() };952matchvtable {953Some(dyn_metadata) => {954letpointer = ptr::from_raw_parts(t, dyn_metadata);955// SAFETY: `t` is a reference to a type, so we know it is valid.956 // `dyn_metadata` is a vtable for T, implementing the trait of `U`.957Some(unsafe{&*pointer })958 }959None=>None,960 }961}962963/// Returns `Some(&mut U)` if `T` can be coerced to the trait object type `U`. Otherwise, it returns `None`.964///965/// # Compile-time failures966/// Determining whether `T` can be coerced to the trait object type `U` requires compiler trait resolution.967/// In some cases, that resolution can exceed the recursion limit,968/// and compilation will fail instead of this function returning `None`.969/// # Examples970///971/// ```rust972/// #![feature(try_as_dyn)]973///974/// use core::any::try_as_dyn_mut;975///976/// trait Animal {977/// fn speak(&self) -> &'static str;978/// }979///980/// struct Dog;981/// impl Animal for Dog {982/// fn speak(&self) -> &'static str { "woof" }983/// }984///985/// struct Rock; // does not implement Animal986///987/// let mut dog = Dog;988/// let mut rock = Rock;989///990/// let as_animal: Option<&mut dyn Animal> = try_as_dyn_mut::<Dog, dyn Animal>(&mut dog);991/// assert_eq!(as_animal.unwrap().speak(), "woof");992///993/// let not_an_animal: Option<&mut dyn Animal> = try_as_dyn_mut::<Rock, dyn Animal>(&mut rock);994/// assert!(not_an_animal.is_none());995/// ```996#[must_use]997#[unstable(feature ="try_as_dyn", issue ="144361")]998pub const fntry_as_dyn_mut<999 T: Any +'static,1000 U: ptr::Pointee<Metadata = ptr::DynMetadata<U>> +?Sized +'static,1001>(1002 t:&mutT,1003) ->Option<&mutU> {1004letvtable:Option<ptr::DynMetadata<U>> =const{ intrinsics::vtable_for::<T, U>() };1005matchvtable {1006Some(dyn_metadata) => {1007letpointer = ptr::from_raw_parts_mut(t, dyn_metadata);1008// SAFETY: `t` is a reference to a type, so we know it is valid.1009 // `dyn_metadata` is a vtable for T, implementing the trait of `U`.1010Some(unsafe{&mut *pointer })1011 }1012None=>None,1013 }1014}