Movatterモバイル変換


[0]ホーム

URL:


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 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}

[8]ページ先頭

©2009-2025 Movatter.jp