core/any.rs
1//! Utilities for dynamic typing or type reflection.
2//!
3//! # `Any` and `TypeId`
4//!
5//! `Any` itself can be used to get a `TypeId`, and has more features when used
6//! as a trait object. As `&dyn Any` (a borrowed trait object), it has the `is`
7//! and `downcast_ref` methods, to test if the contained value is of a given type,
8//! and to get a reference to the inner value as a type. As `&mut dyn Any`, there
9//! is also the `downcast_mut` method, for getting a mutable reference to the
10//! inner value. `Box<dyn Any>` adds the `downcast` method, which attempts to
11//! convert to a `Box<T>`. See the [`Box`] documentation for the full details.
12//!
13//! Note that `&dyn Any` is limited to testing whether a value is of a specified
14//! concrete type, and cannot be used to test whether a type implements a trait.
15//!
16//! [`Box`]: ../../std/boxed/struct.Box.html
17//!
18//! # Smart pointers and `dyn Any`
19//!
20//! One piece of behavior to keep in mind when using `Any` as a trait object,
21//! especially with types like `Box<dyn Any>` or `Arc<dyn Any>`, is that simply
22//! calling `.type_id()` on the value will produce the `TypeId` of the
23//! *container*, not the underlying trait object. This can be avoided by
24//! converting the smart pointer into a `&dyn Any` instead, which will return
25//! the object's `TypeId`. For example:
26//!
27//! ```
28//! use std::any::{Any, TypeId};
29//!
30//! let boxed: Box<dyn Any> = Box::new(3_i32);
31//!
32//! // You're more likely to want this:
33//! let actual_id = (&*boxed).type_id();
34//! // ... than this:
35//! let boxed_id = boxed.type_id();
36//!
37//! assert_eq!(actual_id, TypeId::of::<i32>());
38//! assert_eq!(boxed_id, TypeId::of::<Box<dyn Any>>());
39//! ```
40//!
41//! ## Examples
42//!
43//! Consider a situation where we want to log a value passed to a function.
44//! We know the value we're working on implements `Debug`, but we don't know its
45//! concrete type. We want to give special treatment to certain types: in this
46//! case printing out the length of `String` values prior to their value.
47//! We don't know the concrete type of our value at compile time, so we need to
48//! use runtime reflection instead.
49//!
50//! ```rust
51//! use std::fmt::Debug;
52//! use std::any::Any;
53//!
54//! // Logger function for any type that implements `Debug`.
55//! fn log<T: Any + Debug>(value: &T) {
56//! let value_any = value as &dyn Any;
57//!
58//! // Try to convert our value to a `String`. If successful, we want to
59//! // output the `String`'s length as well as its value. If not, it's a
60//! // different type: just print it out unadorned.
61//! match value_any.downcast_ref::<String>() {
62//! Some(as_string) => {
63//! println!("String ({}): {}", as_string.len(), as_string);
64//! }
65//! None => {
66//! println!("{value:?}");
67//! }
68//! }
69//! }
70//!
71//! // This function wants to log its parameter out prior to doing work with it.
72//! fn do_work<T: Any + Debug>(value: &T) {
73//! log(value);
74//! // ...do some other work
75//! }
76//!
77//! fn main() {
78//! let my_string = "Hello World".to_string();
79//! do_work(&my_string);
80//!
81//! let my_i8: i8 = 100;
82//! do_work(&my_i8);
83//! }
84//! ```
85//!
86
87#![stable(feature = "rust1", since = "1.0.0")]
88
89use crate::intrinsics::{self, type_id, type_id_vtable};
90use crate::mem::transmute;
91use crate::mem::type_info::{TraitImpl, TypeKind};
92use crate::{fmt, hash, ptr};
93
94///////////////////////////////////////////////////////////////////////////////
95// Any trait
96///////////////////////////////////////////////////////////////////////////////
97
98/// A trait to emulate dynamic typing.
99///
100/// Most types implement `Any`. However, any type which contains a non-`'static` reference does not.
101/// See the [module-level documentation][mod] for more details.
102///
103/// [mod]: crate::any
104// This trait is not unsafe, though we rely on the specifics of it's sole impl's
105// `type_id` function in unsafe code (e.g., `downcast`). Normally, that would be
106// a problem, but because the only impl of `Any` is a blanket implementation, no
107// other code can implement `Any`.
108//
109// We could plausibly make this trait unsafe -- it would not cause breakage,
110// since we control all the implementations -- but we choose not to as that's
111// both not really necessary and may confuse users about the distinction of
112// unsafe traits and unsafe methods (i.e., `type_id` would still be safe to call,
113// but we would likely want to indicate as such in documentation).
114#[stable(feature = "rust1", since = "1.0.0")]
115#[rustc_diagnostic_item = "Any"]
116pub trait Any: 'static {
117 /// Gets the `TypeId` of `self`.
118 ///
119 /// If called on a `dyn Any` trait object
120 /// (or a trait object of a subtrait of `Any`),
121 /// this returns the `TypeId` of the underlying
122 /// concrete type, not that of `dyn Any` itself.
123 ///
124 /// # Examples
125 ///
126 /// ```
127 /// use std::any::{Any, TypeId};
128 ///
129 /// fn is_string(s: &dyn Any) -> bool {
130 /// TypeId::of::<String>() == s.type_id()
131 /// }
132 ///
133 /// assert_eq!(is_string(&0), false);
134 /// assert_eq!(is_string(&"cookie monster".to_string()), true);
135 /// ```
136 #[stable(feature = "get_type_id", since = "1.34.0")]
137 fn type_id(&self) -> TypeId;
138}
139
140#[stable(feature = "rust1", since = "1.0.0")]
141impl<T: 'static + ?Sized> Any for T {
142 fn type_id(&self) -> TypeId {
143 TypeId::of::<T>()
144 }
145}
146
147///////////////////////////////////////////////////////////////////////////////
148// Extension methods for Any trait objects.
149///////////////////////////////////////////////////////////////////////////////
150
151#[stable(feature = "rust1", since = "1.0.0")]
152impl fmt::Debug for dyn Any {
153 #[ferrocene::prevalidated]
154 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
155 f.debug_struct("Any").finish_non_exhaustive()
156 }
157}
158
159// Ensure that the result of e.g., joining a thread can be printed and
160// hence used with `unwrap`. May eventually no longer be needed if
161// dispatch works with upcasting.
162#[stable(feature = "rust1", since = "1.0.0")]
163impl fmt::Debug for dyn Any + Send {
164 #[ferrocene::prevalidated]
165 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
166 f.debug_struct("Any").finish_non_exhaustive()
167 }
168}
169
170#[stable(feature = "any_send_sync_methods", since = "1.28.0")]
171impl fmt::Debug for dyn Any + Send + Sync {
172 #[ferrocene::prevalidated]
173 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174 f.debug_struct("Any").finish_non_exhaustive()
175 }
176}
177
178impl dyn Any {
179 /// Returns `true` if the inner type is the same as `T`.
180 ///
181 /// # Examples
182 ///
183 /// ```
184 /// use std::any::Any;
185 ///
186 /// fn is_string(s: &dyn Any) {
187 /// if s.is::<String>() {
188 /// println!("It's a string!");
189 /// } else {
190 /// println!("Not a string...");
191 /// }
192 /// }
193 ///
194 /// is_string(&0);
195 /// is_string(&"cookie monster".to_string());
196 /// ```
197 #[stable(feature = "rust1", since = "1.0.0")]
198 #[inline]
199 pub fn is<T: Any>(&self) -> bool {
200 // Get `TypeId` of the type this function is instantiated with.
201 let t = TypeId::of::<T>();
202
203 // Get `TypeId` of the type in the trait object (`self`).
204 let concrete = self.type_id();
205
206 // Compare both `TypeId`s on equality.
207 t == concrete
208 }
209
210 /// Returns some reference to the inner value if it is of type `T`, or
211 /// `None` if it isn't.
212 ///
213 /// # Examples
214 ///
215 /// ```
216 /// use std::any::Any;
217 ///
218 /// fn print_if_string(s: &dyn Any) {
219 /// if let Some(string) = s.downcast_ref::<String>() {
220 /// println!("It's a string({}): '{}'", string.len(), string);
221 /// } else {
222 /// println!("Not a string...");
223 /// }
224 /// }
225 ///
226 /// print_if_string(&0);
227 /// print_if_string(&"cookie monster".to_string());
228 /// ```
229 #[stable(feature = "rust1", since = "1.0.0")]
230 #[inline]
231 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
232 if self.is::<T>() {
233 // SAFETY: just checked whether we are pointing to the correct type, and we can rely on
234 // that check for memory safety because we have implemented Any for all types; no other
235 // impls can exist as they would conflict with our impl.
236 unsafe { Some(self.downcast_unchecked_ref()) }
237 } else {
238 None
239 }
240 }
241
242 /// Returns some mutable reference to the inner value if it is of type `T`, or
243 /// `None` if it isn't.
244 ///
245 /// # Examples
246 ///
247 /// ```
248 /// use std::any::Any;
249 ///
250 /// fn modify_if_u32(s: &mut dyn Any) {
251 /// if let Some(num) = s.downcast_mut::<u32>() {
252 /// *num = 42;
253 /// }
254 /// }
255 ///
256 /// let mut x = 10u32;
257 /// let mut s = "starlord".to_string();
258 ///
259 /// modify_if_u32(&mut x);
260 /// modify_if_u32(&mut s);
261 ///
262 /// assert_eq!(x, 42);
263 /// assert_eq!(&s, "starlord");
264 /// ```
265 #[stable(feature = "rust1", since = "1.0.0")]
266 #[inline]
267 pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
268 if self.is::<T>() {
269 // SAFETY: just checked whether we are pointing to the correct type, and we can rely on
270 // that check for memory safety because we have implemented Any for all types; no other
271 // impls can exist as they would conflict with our impl.
272 unsafe { Some(self.downcast_unchecked_mut()) }
273 } else {
274 None
275 }
276 }
277
278 /// Returns a reference to the inner value as type `dyn T`.
279 ///
280 /// # Examples
281 ///
282 /// ```
283 /// #![feature(downcast_unchecked)]
284 ///
285 /// use std::any::Any;
286 ///
287 /// let x: Box<dyn Any> = Box::new(1_usize);
288 ///
289 /// unsafe {
290 /// assert_eq!(*x.downcast_unchecked_ref::<usize>(), 1);
291 /// }
292 /// ```
293 ///
294 /// # Safety
295 ///
296 /// The contained value must be of type `T`. Calling this method
297 /// with the incorrect type is *undefined behavior*.
298 #[unstable(feature = "downcast_unchecked", issue = "90850")]
299 #[inline]
300 pub unsafe fn downcast_unchecked_ref<T: Any>(&self) -> &T {
301 debug_assert!(self.is::<T>());
302 // SAFETY: caller guarantees that T is the correct type
303 unsafe { &*(self as *const dyn Any as *const T) }
304 }
305
306 /// Returns a mutable reference to the inner value as type `dyn T`.
307 ///
308 /// # Examples
309 ///
310 /// ```
311 /// #![feature(downcast_unchecked)]
312 ///
313 /// use std::any::Any;
314 ///
315 /// let mut x: Box<dyn Any> = Box::new(1_usize);
316 ///
317 /// unsafe {
318 /// *x.downcast_unchecked_mut::<usize>() += 1;
319 /// }
320 ///
321 /// assert_eq!(*x.downcast_ref::<usize>().unwrap(), 2);
322 /// ```
323 ///
324 /// # Safety
325 ///
326 /// The contained value must be of type `T`. Calling this method
327 /// with the incorrect type is *undefined behavior*.
328 #[unstable(feature = "downcast_unchecked", issue = "90850")]
329 #[inline]
330 pub unsafe fn downcast_unchecked_mut<T: Any>(&mut self) -> &mut T {
331 debug_assert!(self.is::<T>());
332 // SAFETY: caller guarantees that T is the correct type
333 unsafe { &mut *(self as *mut dyn Any as *mut T) }
334 }
335}
336
337impl dyn Any + Send {
338 /// Forwards to the method defined on the type `dyn Any`.
339 ///
340 /// # Examples
341 ///
342 /// ```
343 /// use std::any::Any;
344 ///
345 /// fn is_string(s: &(dyn Any + Send)) {
346 /// if s.is::<String>() {
347 /// println!("It's a string!");
348 /// } else {
349 /// println!("Not a string...");
350 /// }
351 /// }
352 ///
353 /// is_string(&0);
354 /// is_string(&"cookie monster".to_string());
355 /// ```
356 #[stable(feature = "rust1", since = "1.0.0")]
357 #[inline]
358 pub fn is<T: Any>(&self) -> bool {
359 <dyn Any>::is::<T>(self)
360 }
361
362 /// Forwards to the method defined on the type `dyn Any`.
363 ///
364 /// # Examples
365 ///
366 /// ```
367 /// use std::any::Any;
368 ///
369 /// fn print_if_string(s: &(dyn Any + Send)) {
370 /// if let Some(string) = s.downcast_ref::<String>() {
371 /// println!("It's a string({}): '{}'", string.len(), string);
372 /// } else {
373 /// println!("Not a string...");
374 /// }
375 /// }
376 ///
377 /// print_if_string(&0);
378 /// print_if_string(&"cookie monster".to_string());
379 /// ```
380 #[stable(feature = "rust1", since = "1.0.0")]
381 #[inline]
382 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
383 <dyn Any>::downcast_ref::<T>(self)
384 }
385
386 /// Forwards to the method defined on the type `dyn Any`.
387 ///
388 /// # Examples
389 ///
390 /// ```
391 /// use std::any::Any;
392 ///
393 /// fn modify_if_u32(s: &mut (dyn Any + Send)) {
394 /// if let Some(num) = s.downcast_mut::<u32>() {
395 /// *num = 42;
396 /// }
397 /// }
398 ///
399 /// let mut x = 10u32;
400 /// let mut s = "starlord".to_string();
401 ///
402 /// modify_if_u32(&mut x);
403 /// modify_if_u32(&mut s);
404 ///
405 /// assert_eq!(x, 42);
406 /// assert_eq!(&s, "starlord");
407 /// ```
408 #[stable(feature = "rust1", since = "1.0.0")]
409 #[inline]
410 pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
411 <dyn Any>::downcast_mut::<T>(self)
412 }
413
414 /// Forwards to the method defined on the type `dyn Any`.
415 ///
416 /// # Examples
417 ///
418 /// ```
419 /// #![feature(downcast_unchecked)]
420 ///
421 /// use std::any::Any;
422 ///
423 /// let x: Box<dyn Any> = Box::new(1_usize);
424 ///
425 /// unsafe {
426 /// assert_eq!(*x.downcast_unchecked_ref::<usize>(), 1);
427 /// }
428 /// ```
429 ///
430 /// # Safety
431 ///
432 /// The contained value must be of type `T`. Calling this method
433 /// with the incorrect type is *undefined behavior*.
434 #[unstable(feature = "downcast_unchecked", issue = "90850")]
435 #[inline]
436 pub unsafe fn downcast_unchecked_ref<T: Any>(&self) -> &T {
437 // SAFETY: guaranteed by caller
438 unsafe { <dyn Any>::downcast_unchecked_ref::<T>(self) }
439 }
440
441 /// Forwards to the method defined on the type `dyn Any`.
442 ///
443 /// # Examples
444 ///
445 /// ```
446 /// #![feature(downcast_unchecked)]
447 ///
448 /// use std::any::Any;
449 ///
450 /// let mut x: Box<dyn Any> = Box::new(1_usize);
451 ///
452 /// unsafe {
453 /// *x.downcast_unchecked_mut::<usize>() += 1;
454 /// }
455 ///
456 /// assert_eq!(*x.downcast_ref::<usize>().unwrap(), 2);
457 /// ```
458 ///
459 /// # Safety
460 ///
461 /// The contained value must be of type `T`. Calling this method
462 /// with the incorrect type is *undefined behavior*.
463 #[unstable(feature = "downcast_unchecked", issue = "90850")]
464 #[inline]
465 pub unsafe fn downcast_unchecked_mut<T: Any>(&mut self) -> &mut T {
466 // SAFETY: guaranteed by caller
467 unsafe { <dyn Any>::downcast_unchecked_mut::<T>(self) }
468 }
469}
470
471impl dyn Any + Send + Sync {
472 /// Forwards to the method defined on the type `Any`.
473 ///
474 /// # Examples
475 ///
476 /// ```
477 /// use std::any::Any;
478 ///
479 /// fn is_string(s: &(dyn Any + Send + Sync)) {
480 /// if s.is::<String>() {
481 /// println!("It's a string!");
482 /// } else {
483 /// println!("Not a string...");
484 /// }
485 /// }
486 ///
487 /// is_string(&0);
488 /// is_string(&"cookie monster".to_string());
489 /// ```
490 #[stable(feature = "any_send_sync_methods", since = "1.28.0")]
491 #[inline]
492 pub fn is<T: Any>(&self) -> bool {
493 <dyn Any>::is::<T>(self)
494 }
495
496 /// Forwards to the method defined on the type `Any`.
497 ///
498 /// # Examples
499 ///
500 /// ```
501 /// use std::any::Any;
502 ///
503 /// fn print_if_string(s: &(dyn Any + Send + Sync)) {
504 /// if let Some(string) = s.downcast_ref::<String>() {
505 /// println!("It's a string({}): '{}'", string.len(), string);
506 /// } else {
507 /// println!("Not a string...");
508 /// }
509 /// }
510 ///
511 /// print_if_string(&0);
512 /// print_if_string(&"cookie monster".to_string());
513 /// ```
514 #[stable(feature = "any_send_sync_methods", since = "1.28.0")]
515 #[inline]
516 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
517 <dyn Any>::downcast_ref::<T>(self)
518 }
519
520 /// Forwards to the method defined on the type `Any`.
521 ///
522 /// # Examples
523 ///
524 /// ```
525 /// use std::any::Any;
526 ///
527 /// fn modify_if_u32(s: &mut (dyn Any + Send + Sync)) {
528 /// if let Some(num) = s.downcast_mut::<u32>() {
529 /// *num = 42;
530 /// }
531 /// }
532 ///
533 /// let mut x = 10u32;
534 /// let mut s = "starlord".to_string();
535 ///
536 /// modify_if_u32(&mut x);
537 /// modify_if_u32(&mut s);
538 ///
539 /// assert_eq!(x, 42);
540 /// assert_eq!(&s, "starlord");
541 /// ```
542 #[stable(feature = "any_send_sync_methods", since = "1.28.0")]
543 #[inline]
544 pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
545 <dyn Any>::downcast_mut::<T>(self)
546 }
547
548 /// Forwards to the method defined on the type `Any`.
549 ///
550 /// # Examples
551 ///
552 /// ```
553 /// #![feature(downcast_unchecked)]
554 ///
555 /// use std::any::Any;
556 ///
557 /// let x: Box<dyn Any> = Box::new(1_usize);
558 ///
559 /// unsafe {
560 /// assert_eq!(*x.downcast_unchecked_ref::<usize>(), 1);
561 /// }
562 /// ```
563 /// # Safety
564 ///
565 /// The contained value must be of type `T`. Calling this method
566 /// with the incorrect type is *undefined behavior*.
567 #[unstable(feature = "downcast_unchecked", issue = "90850")]
568 #[inline]
569 pub unsafe fn downcast_unchecked_ref<T: Any>(&self) -> &T {
570 // SAFETY: guaranteed by caller
571 unsafe { <dyn Any>::downcast_unchecked_ref::<T>(self) }
572 }
573
574 /// Forwards to the method defined on the type `Any`.
575 ///
576 /// # Examples
577 ///
578 /// ```
579 /// #![feature(downcast_unchecked)]
580 ///
581 /// use std::any::Any;
582 ///
583 /// let mut x: Box<dyn Any> = Box::new(1_usize);
584 ///
585 /// unsafe {
586 /// *x.downcast_unchecked_mut::<usize>() += 1;
587 /// }
588 ///
589 /// assert_eq!(*x.downcast_ref::<usize>().unwrap(), 2);
590 /// ```
591 /// # Safety
592 ///
593 /// The contained value must be of type `T`. Calling this method
594 /// with the incorrect type is *undefined behavior*.
595 #[unstable(feature = "downcast_unchecked", issue = "90850")]
596 #[inline]
597 pub unsafe fn downcast_unchecked_mut<T: Any>(&mut self) -> &mut T {
598 // SAFETY: guaranteed by caller
599 unsafe { <dyn Any>::downcast_unchecked_mut::<T>(self) }
600 }
601}
602
603///////////////////////////////////////////////////////////////////////////////
604// TypeID and its methods
605///////////////////////////////////////////////////////////////////////////////
606
607/// A `TypeId` represents a globally unique identifier for a type.
608///
609/// Each `TypeId` is an opaque object which does not allow inspection of what's
610/// inside but does allow basic operations such as cloning, comparison,
611/// printing, and showing.
612///
613/// A `TypeId` is currently only available for types which ascribe to `'static`,
614/// but this limitation may be removed in the future.
615///
616/// While `TypeId` implements `Hash`, `PartialOrd`, and `Ord`, it is worth
617/// noting that the hashes and ordering will vary between Rust releases. Beware
618/// of relying on them inside of your code!
619///
620/// # Layout
621///
622/// Like other [`Rust`-representation][repr-rust] types, `TypeId`'s size and layout are unstable.
623/// In particular, this means that you cannot rely on the size and layout of `TypeId` remaining the
624/// same between Rust releases; they are subject to change without prior notice between Rust
625/// releases.
626///
627/// [repr-rust]: https://doc.rust-lang.org/reference/type-layout.html#r-layout.repr.rust.unspecified
628///
629/// # Danger of Improper Variance
630///
631/// You might think that subtyping is impossible between two static types,
632/// but this is false; there exists a static type with a static subtype.
633/// To wit, `fn(&str)`, which is short for `for<'any> fn(&'any str)`, and
634/// `fn(&'static str)`, are two distinct, static types, and yet,
635/// `fn(&str)` is a subtype of `fn(&'static str)`, since any value of type
636/// `fn(&str)` can be used where a value of type `fn(&'static str)` is needed.
637///
638/// This means that abstractions around `TypeId`, despite its
639/// `'static` bound on arguments, still need to worry about unnecessary
640/// and improper variance: it is advisable to strive for invariance
641/// first. The usability impact will be negligible, while the reduction
642/// in the risk of unsoundness will be most welcome.
643///
644/// ## Examples
645///
646/// Suppose `SubType` is a subtype of `SuperType`, that is,
647/// a value of type `SubType` can be used wherever
648/// a value of type `SuperType` is expected.
649/// Suppose also that `CoVar<T>` is a generic type, which is covariant over `T`
650/// (like many other types, including `PhantomData<T>` and `Vec<T>`).
651///
652/// Then, by covariance, `CoVar<SubType>` is a subtype of `CoVar<SuperType>`,
653/// that is, a value of type `CoVar<SubType>` can be used wherever
654/// a value of type `CoVar<SuperType>` is expected.
655///
656/// Then if `CoVar<SuperType>` relies on `TypeId::of::<SuperType>()` to uphold any invariants,
657/// those invariants may be broken because a value of type `CoVar<SuperType>` can be created
658/// without going through any of its methods, like so:
659/// ```
660/// type SubType = fn(&());
661/// type SuperType = fn(&'static ());
662/// type CoVar<T> = Vec<T>; // imagine something more complicated
663///
664/// let sub: CoVar<SubType> = CoVar::new();
665/// // we have a `CoVar<SuperType>` instance without
666/// // *ever* having called `CoVar::<SuperType>::new()`!
667/// let fake_super: CoVar<SuperType> = sub;
668/// ```
669///
670/// The following is an example program that tries to use `TypeId::of` to
671/// implement a generic type `Unique<T>` that guarantees unique instances for each `Unique<T>`,
672/// that is, for each type `T` there can be at most one value of type `Unique<T>` at any time.
673///
674/// ```
675/// mod unique {
676/// use std::any::TypeId;
677/// use std::collections::BTreeSet;
678/// use std::marker::PhantomData;
679/// use std::sync::Mutex;
680///
681/// static ID_SET: Mutex<BTreeSet<TypeId>> = Mutex::new(BTreeSet::new());
682///
683/// // TypeId has only covariant uses, which makes Unique covariant over TypeAsId 🚨
684/// #[derive(Debug, PartialEq)]
685/// pub struct Unique<TypeAsId: 'static>(
686/// // private field prevents creation without `new` outside this module
687/// PhantomData<TypeAsId>,
688/// );
689///
690/// impl<TypeAsId: 'static> Unique<TypeAsId> {
691/// pub fn new() -> Option<Self> {
692/// let mut set = ID_SET.lock().unwrap();
693/// (set.insert(TypeId::of::<TypeAsId>())).then(|| Self(PhantomData))
694/// }
695/// }
696///
697/// impl<TypeAsId: 'static> Drop for Unique<TypeAsId> {
698/// fn drop(&mut self) {
699/// let mut set = ID_SET.lock().unwrap();
700/// (!set.remove(&TypeId::of::<TypeAsId>())).then(|| panic!("duplicity detected"));
701/// }
702/// }
703/// }
704///
705/// use unique::Unique;
706///
707/// // `OtherRing` is a subtype of `TheOneRing`. Both are 'static, and thus have a TypeId.
708/// type TheOneRing = fn(&'static ());
709/// type OtherRing = fn(&());
710///
711/// fn main() {
712/// let the_one_ring: Unique<TheOneRing> = Unique::new().unwrap();
713/// assert_eq!(Unique::<TheOneRing>::new(), None);
714///
715/// let other_ring: Unique<OtherRing> = Unique::new().unwrap();
716/// // Use that `Unique<OtherRing>` is a subtype of `Unique<TheOneRing>` 🚨
717/// let fake_one_ring: Unique<TheOneRing> = other_ring;
718/// assert_eq!(fake_one_ring, the_one_ring);
719///
720/// std::mem::forget(fake_one_ring);
721/// }
722/// ```
723#[derive(Copy, PartialOrd, Ord)]
724#[derive_const(Clone, Eq)]
725#[stable(feature = "rust1", since = "1.0.0")]
726#[lang = "type_id"]
727#[ferrocene::prevalidated]
728pub struct TypeId {
729 /// This needs to be an array of pointers, since there is provenance
730 /// in the first array field. This provenance knows exactly which type
731 /// the TypeId actually is, allowing CTFE and miri to operate based off it.
732 /// At runtime all the pointers in the array contain bits of the hash, making
733 /// the entire `TypeId` actually just be a `u128` hash of the type.
734 pub(crate) data: [*const (); 16 / size_of::<*const ()>()],
735}
736
737// SAFETY: the raw pointer is always an integer
738#[stable(feature = "rust1", since = "1.0.0")]
739unsafe impl Send for TypeId {}
740// SAFETY: the raw pointer is always an integer
741#[stable(feature = "rust1", since = "1.0.0")]
742unsafe impl Sync for TypeId {}
743
744#[stable(feature = "rust1", since = "1.0.0")]
745#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
746const impl PartialEq for TypeId {
747 #[inline]
748 #[ferrocene::prevalidated]
749 fn eq(&self, other: &Self) -> bool {
750 crate::intrinsics::type_id_eq(*self, *other)
751 }
752}
753
754impl TypeId {
755 /// Returns the `TypeId` of the generic type parameter.
756 ///
757 /// # Examples
758 ///
759 /// ```
760 /// use std::any::{Any, TypeId};
761 ///
762 /// fn is_string<T: ?Sized + Any>(_s: &T) -> bool {
763 /// TypeId::of::<String>() == TypeId::of::<T>()
764 /// }
765 ///
766 /// assert_eq!(is_string(&0), false);
767 /// assert_eq!(is_string(&"cookie monster".to_string()), true);
768 /// ```
769 #[must_use]
770 #[stable(feature = "rust1", since = "1.0.0")]
771 #[rustc_const_stable(feature = "const_type_id", since = "1.91.0")]
772 #[ferrocene::prevalidated]
773 pub const fn of<T: ?Sized + 'static>() -> TypeId {
774 const { intrinsics::type_id::<T>() }
775 }
776
777 /// Checks if the [TypeId] implements the trait. If it does it returns [TraitImpl] which can be used to build a fat pointer.
778 /// It can only be called at compile time. `self` must be the [TypeId] of a sized type or None will be returned.
779 ///
780 /// # Examples
781 ///
782 /// ```
783 /// #![feature(type_info)]
784 /// use std::any::{TypeId};
785 ///
786 /// pub trait Blah {}
787 /// impl Blah for u8 {}
788 ///
789 /// assert!(const { TypeId::of::<u8>().trait_info_of::<dyn Blah>() }.is_some());
790 /// assert!(const { TypeId::of::<u16>().trait_info_of::<dyn Blah>() }.is_none());
791 /// ```
792 #[unstable(feature = "type_info", issue = "146922")]
793 #[rustc_const_unstable(feature = "type_info", issue = "146922")]
794 #[rustc_comptime]
795 pub fn trait_info_of<'a, T: TryAsDynCompatible<'a> + ?Sized>(self) -> Option<TraitImpl<T>> {
796 // SAFETY: The vtable was obtained for `T`, so it is guaranteed to be `DynMetadata<T>`.
797 // The intrinsic can't infer this because it is designed to work with arbitrary TypeIds.
798 unsafe { transmute(self.trait_info_of_trait_type_id(const { type_id::<T>() })) }
799 }
800
801 /// Checks if the [TypeId] implements the trait of `trait_represented_by_type_id`. If it does it returns [TraitImpl] which can be used to build a fat pointer.
802 /// It can only be called at compile time. `self` must be the [TypeId] of a sized type or None will be returned.
803 ///
804 /// # Examples
805 ///
806 /// ```
807 /// #![feature(type_info)]
808 /// use std::any::{TypeId};
809 ///
810 /// pub trait Blah {}
811 /// impl Blah for u8 {}
812 ///
813 /// assert!(const { TypeId::of::<u8>().trait_info_of_trait_type_id(TypeId::of::<dyn Blah>()) }.is_some());
814 /// assert!(const { TypeId::of::<u16>().trait_info_of_trait_type_id(TypeId::of::<dyn Blah>()) }.is_none());
815 /// ```
816 #[unstable(feature = "type_info", issue = "146922")]
817 #[rustc_const_unstable(feature = "type_info", issue = "146922")]
818 #[rustc_comptime]
819 pub fn trait_info_of_trait_type_id(
820 self,
821 trait_represented_by_type_id: TypeId,
822 ) -> Option<TraitImpl<*const ()>> {
823 if self.size().is_none() {
824 return None;
825 }
826
827 if matches!(trait_represented_by_type_id.info().kind, TypeKind::DynTrait(_))
828 && let Some(vtable) = type_id_vtable(self, trait_represented_by_type_id)
829 {
830 Some(TraitImpl { vtable })
831 } else {
832 None
833 }
834 }
835
836 #[ferrocene::prevalidated]
837 pub(crate) fn as_u128(self) -> u128 {
838 let mut bytes = [0; 16];
839
840 // This is a provenance-stripping memcpy.
841 for (i, chunk) in self.data.iter().copied().enumerate() {
842 let chunk = chunk.addr().to_ne_bytes();
843 let start = i * chunk.len();
844 bytes[start..(start + chunk.len())].copy_from_slice(&chunk);
845 }
846 u128::from_ne_bytes(bytes)
847 }
848}
849
850#[stable(feature = "rust1", since = "1.0.0")]
851impl hash::Hash for TypeId {
852 #[inline]
853 fn hash<H: hash::Hasher>(&self, state: &mut H) {
854 // We only hash the lower 64 bits of our (128 bit) internal numeric ID,
855 // because:
856 // - The hashing algorithm which backs `TypeId` is expected to be
857 // unbiased and high quality, meaning further mixing would be somewhat
858 // redundant compared to choosing (the lower) 64 bits arbitrarily.
859 // - `Hasher::finish` returns a u64 anyway, so the extra entropy we'd
860 // get from hashing the full value would probably not be useful
861 // (especially given the previous point about the lower 64 bits being
862 // high quality on their own).
863 // - It is correct to do so -- only hashing a subset of `self` is still
864 // compatible with an `Eq` implementation that considers the entire
865 // value, as ours does.
866 let data =
867 // SAFETY: The `offset` stays in-bounds, it just moves the pointer to the 2nd half of the `TypeId`.
868 // Only the first ptr-sized chunk ever has provenance, so that second half is always
869 // fine to read at integer type.
870 unsafe { crate::ptr::read_unaligned(self.data.as_ptr().cast::<u64>().offset(1)) };
871 data.hash(state);
872 }
873}
874
875#[stable(feature = "rust1", since = "1.0.0")]
876impl fmt::Debug for TypeId {
877 #[ferrocene::prevalidated]
878 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
879 write!(f, "TypeId({:#034x})", self.as_u128())
880 }
881}
882
883/// Returns the name of a type as a string slice.
884///
885/// # Note
886///
887/// This is intended for diagnostic use. The exact contents and format of the
888/// string returned are not specified, other than being a best-effort
889/// description of the type. For example, amongst the strings
890/// that `type_name::<Option<String>>()` might return are `"Option<String>"` and
891/// `"std::option::Option<std::string::String>"`.
892///
893/// The returned string must not be considered to be a unique identifier of a
894/// type as multiple types may map to the same type name. Similarly, there is no
895/// guarantee that all parts of a type will appear in the returned string. In
896/// addition, the output may change between versions of the compiler. For
897/// example, lifetime specifiers were omitted in some earlier versions.
898///
899/// The current implementation uses the same infrastructure as compiler
900/// diagnostics and debuginfo, but this is not guaranteed.
901///
902/// # Examples
903///
904/// ```rust
905/// assert_eq!(
906/// std::any::type_name::<Option<String>>(),
907/// "core::option::Option<alloc::string::String>",
908/// );
909/// ```
910#[must_use]
911#[stable(feature = "type_name", since = "1.38.0")]
912#[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
913#[ferrocene::prevalidated]
914pub const fn type_name<T: ?Sized>() -> &'static str {
915 const { intrinsics::type_name::<T>() }
916}
917
918/// Returns the type name of the pointed-to value as a string slice.
919///
920/// This is the same as `type_name::<T>()`, but can be used where the type of a
921/// variable is not easily available.
922///
923/// # Note
924///
925/// Like [`type_name`], this is intended for diagnostic use and the exact output is not
926/// guaranteed. It provides a best-effort description, but the output may change between
927/// versions of the compiler.
928///
929/// In short: use this for debugging, avoid using the output to affect program behavior. More
930/// information is available at [`type_name`].
931///
932/// Additionally, this function does not resolve trait objects. This means that
933/// `type_name_of_val(&7u32 as &dyn Debug)` may return `"dyn Debug"`, but will not return `"u32"`
934/// at this time.
935///
936/// # Examples
937///
938/// Prints the default integer and float types.
939///
940/// ```rust
941/// use std::any::type_name_of_val;
942///
943/// let s = "foo";
944/// let x: i32 = 1;
945/// let y: f32 = 1.0;
946///
947/// assert!(type_name_of_val(&s).contains("str"));
948/// assert!(type_name_of_val(&x).contains("i32"));
949/// assert!(type_name_of_val(&y).contains("f32"));
950/// ```
951#[must_use]
952#[stable(feature = "type_name_of_val", since = "1.76.0")]
953#[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
954#[ferrocene::prevalidated]
955pub const fn type_name_of_val<T: ?Sized>(_val: &T) -> &'static str {
956 type_name::<T>()
957}
958
959/// Trait that is automatically implemented for all `dyn Trait<'b, C> + 'a` without assoc type bounds.
960/// The lifetime parameter should be the same that is used to constrain generic type parameters
961/// that are turned into the dyn trait constrained by `TryAsDynCompatible`.
962///
963/// This is required for `try_as_dyn` to be able to soundly convert non-static
964/// types to `dyn Trait`.
965///
966/// Note: these requirements are sufficient for soundness, but it is unclear
967/// if they are all necessary. We may be able to lift some requirements in favor
968/// of more precise ones.
969///
970#[unstable(feature = "try_as_dyn", issue = "144361")]
971#[lang = "try_as_dyn"]
972#[rustc_deny_explicit_impl]
973pub trait TryAsDynCompatible<'a>: ptr::Pointee<Metadata = ptr::DynMetadata<Self>> {}
974
975/// Returns `Some(&U)` if `T` can be coerced to the dyn trait type `U`. Otherwise, it returns `None`.
976///
977/// # Run-time failures
978///
979/// There are multiple ways to get a `None`, and you need to manually analyze which one it is, as the
980/// compiler does not provide any help here.
981///
982/// * `T` does not implement `Trait` at all,
983/// * `T`'s impl for `Trait` is not fully generic,
984/// * `T`'s impl for `Trait` is a builtin impl (e.g. `dyn Debug` implements `Debug`)
985///
986/// There is some detailed documentation about this feature at
987/// <https://doc.rust-lang.org/unstable-book/language-features/try_as_dyn.html>
988/// But the gist is summarized below:
989///
990/// ## Lifetime-independent impls
991///
992/// `try_as_dyn` does not have access to lifetime information, thus it cannot differentiate between
993/// `'static`, other lifetimes, and can't reason about outlives bounds on impls. Thus we can only accept
994/// impls that do not have `'static` lifetimes, or outlives bounds of any kind. You can have simple
995/// trait bounds, and the compiler will transitively only use impls of those simple trait bounds that satisfy
996/// the same rules as the main trait you're converting to.
997///
998/// An example of a legal impl is:
999///
1000/// ```rust
1001/// # trait Trait<'a, T> {}
1002/// # struct Type<'b, U>(&'b U);
1003/// # use std::fmt::{Debug, Display};
1004/// impl<'a, 'b, T: Debug, U: Display> Trait<'a, T> for Type<'b, U> {}
1005/// ```
1006///
1007/// Impls without generic parameters at all are also legal, as long as they contain no `'static` lifetimes.
1008///
1009/// ## Builtin impls
1010///
1011/// Builtin impls (like `impl Debug for dyn Debug`) have various obscure rules and often are not fully generic.
1012/// To simplify reasoning about what is allowed and what not, all builtin impls are rejected and will neither
1013/// directly nor indirectly contribute to a `Some` result.
1014///
1015/// # Compile-time failures
1016/// Determining whether `T` can be coerced to the dyn trait type `U` requires compiler trait resolution.
1017/// In some cases, that resolution can exceed the recursion limit,
1018/// and compilation will fail instead of this function returning `None`.
1019///
1020/// The input type `T` must outlive the lifetime `'a` on the `dyn Trait + 'a`.
1021/// This is basically the same rule that forbids `let x: &dyn Trait + 'static = &&some_local_variable;`
1022/// So if you see borrow check errors around `try_as_dyn`, think about whether a normal unsizing
1023/// coercion would be possible at all if you were using concrete types or had bounds on the input type.
1024///
1025/// # Examples
1026///
1027/// ```rust
1028/// #![feature(try_as_dyn)]
1029///
1030/// use core::any::try_as_dyn;
1031///
1032/// trait Animal {
1033/// fn speak(&self) -> &'static str;
1034/// }
1035///
1036/// struct Dog;
1037/// impl Animal for Dog {
1038/// fn speak(&self) -> &'static str { "woof" }
1039/// }
1040///
1041/// struct Rock; // does not implement Animal
1042///
1043/// let dog = Dog;
1044/// let rock = Rock;
1045///
1046/// let as_animal: Option<&dyn Animal> = try_as_dyn::<Dog, dyn Animal>(&dog);
1047/// assert_eq!(as_animal.unwrap().speak(), "woof");
1048///
1049/// let not_an_animal: Option<&dyn Animal> = try_as_dyn::<Rock, dyn Animal>(&rock);
1050/// assert!(not_an_animal.is_none());
1051/// ```
1052#[must_use]
1053#[unstable(feature = "try_as_dyn", issue = "144361")]
1054pub const fn try_as_dyn<'a, T: ?Sized + 'a, U: TryAsDynCompatible<'a> + ?Sized>(
1055 t: &T,
1056) -> Option<&U> {
1057 // For unsized `T`, `trait_info_of` always returns `None` (vtable lookup is
1058 // only supported for sized types). The function therefore unconditionally
1059 // returns `None` in that case.
1060 let vtable: Option<ptr::DynMetadata<U>> =
1061 const { type_id::<T>().trait_info_of::<U>().as_ref().map(TraitImpl::get_vtable) };
1062 match vtable {
1063 Some(dyn_metadata) => {
1064 let pointer = ptr::from_raw_parts(t as *const T as *const (), dyn_metadata);
1065 // SAFETY: `t` is a reference to a type, so we know it is valid.
1066 // `dyn_metadata` is a vtable for T, implementing the trait of `U`.
1067 // `T` is sized here because `trait_info_of` only returns `Some` for sized types,
1068 // so the thin data pointer fully describes the value.
1069 Some(unsafe { &*pointer })
1070 }
1071 None => None,
1072 }
1073}
1074
1075/// Returns `Some(&mut U)` if `T` can be coerced to the trait object type `U`. Otherwise, it returns `None`.
1076///
1077/// See documentation of [try_as_dyn] for details about the behaviour and limitations.
1078#[must_use]
1079#[unstable(feature = "try_as_dyn", issue = "144361")]
1080pub const fn try_as_dyn_mut<'a, T: ?Sized + 'a, U: TryAsDynCompatible<'a> + ?Sized>(
1081 t: &mut T,
1082) -> Option<&mut U> {
1083 // For unsized `T`, `trait_info_of` always returns `None` (vtable lookup is
1084 // only supported for sized types). The function therefore unconditionally
1085 // returns `None` in that case.
1086 let vtable: Option<ptr::DynMetadata<U>> =
1087 const { type_id::<T>().trait_info_of::<U>().as_ref().map(TraitImpl::get_vtable) };
1088 match vtable {
1089 Some(dyn_metadata) => {
1090 let pointer = ptr::from_raw_parts_mut(t as *mut T as *mut (), dyn_metadata);
1091 // SAFETY: `t` is a reference to a type, so we know it is valid.
1092 // `dyn_metadata` is a vtable for T, implementing the trait of `U`.
1093 // `T` is sized here because `trait_info_of` only returns `Some` for sized types,
1094 // so the thin data pointer fully describes the value.
1095 Some(unsafe { &mut *pointer })
1096 }
1097 None => None,
1098 }
1099}