1 //! This module contains the `Any` trait, which enables dynamic typing
2 //! of any `'static` type through runtime reflection. It also contains the
3 //! `Provider` trait and accompanying API, which enable trait objects to provide
4 //! data based on typed requests, an alternate form of runtime reflection.
6 //! # `Any` and `TypeId`
8 //! `Any` itself can be used to get a `TypeId`, and has more features when used
9 //! as a trait object. As `&dyn Any` (a borrowed trait object), it has the `is`
10 //! and `downcast_ref` methods, to test if the contained value is of a given type,
11 //! and to get a reference to the inner value as a type. As `&mut dyn Any`, there
12 //! is also the `downcast_mut` method, for getting a mutable reference to the
13 //! inner value. `Box<dyn Any>` adds the `downcast` method, which attempts to
14 //! convert to a `Box<T>`. See the [`Box`] documentation for the full details.
16 //! Note that `&dyn Any` is limited to testing whether a value is of a specified
17 //! concrete type, and cannot be used to test whether a type implements a trait.
19 //! [`Box`]: ../../std/boxed/struct.Box.html
21 //! # Smart pointers and `dyn Any`
23 //! One piece of behavior to keep in mind when using `Any` as a trait object,
24 //! especially with types like `Box<dyn Any>` or `Arc<dyn Any>`, is that simply
25 //! calling `.type_id()` on the value will produce the `TypeId` of the
26 //! *container*, not the underlying trait object. This can be avoided by
27 //! converting the smart pointer into a `&dyn Any` instead, which will return
28 //! the object's `TypeId`. For example:
31 //! use std::any::{Any, TypeId};
33 //! let boxed: Box<dyn Any> = Box::new(3_i32);
35 //! // You're more likely to want this:
36 //! let actual_id = (&*boxed).type_id();
38 //! let boxed_id = boxed.type_id();
40 //! assert_eq!(actual_id, TypeId::of::<i32>());
41 //! assert_eq!(boxed_id, TypeId::of::<Box<dyn Any>>());
46 //! Consider a situation where we want to log out a value passed to a function.
47 //! We know the value we're working on implements Debug, but we don't know its
48 //! concrete type. We want to give special treatment to certain types: in this
49 //! case printing out the length of String values prior to their value.
50 //! We don't know the concrete type of our value at compile time, so we need to
51 //! use runtime reflection instead.
54 //! use std::fmt::Debug;
55 //! use std::any::Any;
57 //! // Logger function for any type that implements Debug.
58 //! fn log<T: Any + Debug>(value: &T) {
59 //! let value_any = value as &dyn Any;
61 //! // Try to convert our value to a `String`. If successful, we want to
62 //! // output the String`'s length as well as its value. If not, it's a
63 //! // different type: just print it out unadorned.
64 //! match value_any.downcast_ref::<String>() {
65 //! Some(as_string) => {
66 //! println!("String ({}): {}", as_string.len(), as_string);
69 //! println!("{value:?}");
74 //! // This function wants to log its parameter out prior to doing work with it.
75 //! fn do_work<T: Any + Debug>(value: &T) {
77 //! // ...do some other work
81 //! let my_string = "Hello World".to_string();
82 //! do_work(&my_string);
84 //! let my_i8: i8 = 100;
89 //! # `Provider` and `Demand`
91 //! `Provider` and the associated APIs support generic, type-driven access to data, and a mechanism
92 //! for implementers to provide such data. The key parts of the interface are the `Provider`
93 //! trait for objects which can provide data, and the [`request_value`] and [`request_ref`]
94 //! functions for requesting data from an object which implements `Provider`. Generally, end users
95 //! should not call `request_*` directly, they are helper functions for intermediate implementers
96 //! to use to implement a user-facing interface. This is purely for the sake of ergonomics, there is
97 //! no safety concern here; intermediate implementers can typically support methods rather than
98 //! free functions and use more specific names.
100 //! Typically, a data provider is a trait object of a trait which extends `Provider`. A user will
101 //! request data from a trait object by specifying the type of the data.
105 //! * A user requests an object of a specific type, which is delegated to `request_value` or
107 //! * `request_*` creates a `Demand` object and passes it to `Provider::provide`
108 //! * The data provider's implementation of `Provider::provide` tries providing values of
109 //! different types using `Demand::provide_*`. If the type matches the type requested by
110 //! the user, the value will be stored in the `Demand` object.
111 //! * `request_*` unpacks the `Demand` object and returns any stored value to the user.
116 //! # #![feature(provide_any)]
117 //! use std::any::{Provider, Demand, request_ref};
119 //! // Definition of MyTrait, a data provider.
120 //! trait MyTrait: Provider {
124 //! // Methods on `MyTrait` trait objects.
125 //! impl dyn MyTrait + '_ {
126 //! /// Get a reference to a field of the implementing struct.
127 //! pub fn get_context_by_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
128 //! request_ref::<T, _>(self)
132 //! // Downstream implementation of `MyTrait` and `Provider`.
133 //! # struct SomeConcreteType { some_string: String }
134 //! impl MyTrait for SomeConcreteType {
138 //! impl Provider for SomeConcreteType {
139 //! fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
140 //! // Provide a string reference. We could provide multiple values with
141 //! // different types here.
142 //! demand.provide_ref::<String>(&self.some_string);
146 //! // Downstream usage of `MyTrait`.
147 //! fn use_my_trait(obj: &dyn MyTrait) {
148 //! // Request a &String from obj.
149 //! let _ = obj.get_context_by_ref::<String>().unwrap();
153 //! In this example, if the concrete type of `obj` in `use_my_trait` is `SomeConcreteType`, then
154 //! the `get_context_ref` call will return a reference to `obj.some_string` with type `&String`.
156 #![stable(feature = "rust1", since = "1.0.0")]
159 use crate::intrinsics;
161 ///////////////////////////////////////////////////////////////////////////////
163 ///////////////////////////////////////////////////////////////////////////////
165 /// A trait to emulate dynamic typing.
167 /// Most types implement `Any`. However, any type which contains a non-`'static` reference does not.
168 /// See the [module-level documentation][mod] for more details.
170 /// [mod]: crate::any
171 // This trait is not unsafe, though we rely on the specifics of it's sole impl's
172 // `type_id` function in unsafe code (e.g., `downcast`). Normally, that would be
173 // a problem, but because the only impl of `Any` is a blanket implementation, no
174 // other code can implement `Any`.
176 // We could plausibly make this trait unsafe -- it would not cause breakage,
177 // since we control all the implementations -- but we choose not to as that's
178 // both not really necessary and may confuse users about the distinction of
179 // unsafe traits and unsafe methods (i.e., `type_id` would still be safe to call,
180 // but we would likely want to indicate as such in documentation).
181 #[stable(feature = "rust1", since = "1.0.0")]
182 #[cfg_attr(not(test), rustc_diagnostic_item = "Any")]
183 pub trait Any: 'static {
184 /// Gets the `TypeId` of `self`.
189 /// use std::any::{Any, TypeId};
191 /// fn is_string(s: &dyn Any) -> bool {
192 /// TypeId::of::<String>() == s.type_id()
195 /// assert_eq!(is_string(&0), false);
196 /// assert_eq!(is_string(&"cookie monster".to_string()), true);
198 #[stable(feature = "get_type_id", since = "1.34.0")]
199 fn type_id(&self) -> TypeId;
202 #[stable(feature = "rust1", since = "1.0.0")]
203 impl<T: 'static + ?Sized> Any for T {
204 fn type_id(&self) -> TypeId {
209 ///////////////////////////////////////////////////////////////////////////////
210 // Extension methods for Any trait objects.
211 ///////////////////////////////////////////////////////////////////////////////
213 #[stable(feature = "rust1", since = "1.0.0")]
214 impl fmt::Debug for dyn Any {
215 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
216 f.debug_struct("Any").finish_non_exhaustive()
220 // Ensure that the result of e.g., joining a thread can be printed and
221 // hence used with `unwrap`. May eventually no longer be needed if
222 // dispatch works with upcasting.
223 #[stable(feature = "rust1", since = "1.0.0")]
224 impl fmt::Debug for dyn Any + Send {
225 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
226 f.debug_struct("Any").finish_non_exhaustive()
230 #[stable(feature = "any_send_sync_methods", since = "1.28.0")]
231 impl fmt::Debug for dyn Any + Send + Sync {
232 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233 f.debug_struct("Any").finish_non_exhaustive()
238 /// Returns `true` if the inner type is the same as `T`.
243 /// use std::any::Any;
245 /// fn is_string(s: &dyn Any) {
246 /// if s.is::<String>() {
247 /// println!("It's a string!");
249 /// println!("Not a string...");
254 /// is_string(&"cookie monster".to_string());
256 #[stable(feature = "rust1", since = "1.0.0")]
258 pub fn is<T: Any>(&self) -> bool {
259 // Get `TypeId` of the type this function is instantiated with.
260 let t = TypeId::of::<T>();
262 // Get `TypeId` of the type in the trait object (`self`).
263 let concrete = self.type_id();
265 // Compare both `TypeId`s on equality.
269 /// Returns some reference to the inner value if it is of type `T`, or
270 /// `None` if it isn't.
275 /// use std::any::Any;
277 /// fn print_if_string(s: &dyn Any) {
278 /// if let Some(string) = s.downcast_ref::<String>() {
279 /// println!("It's a string({}): '{}'", string.len(), string);
281 /// println!("Not a string...");
285 /// print_if_string(&0);
286 /// print_if_string(&"cookie monster".to_string());
288 #[stable(feature = "rust1", since = "1.0.0")]
290 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
292 // SAFETY: just checked whether we are pointing to the correct type, and we can rely on
293 // that check for memory safety because we have implemented Any for all types; no other
294 // impls can exist as they would conflict with our impl.
295 unsafe { Some(self.downcast_ref_unchecked()) }
301 /// Returns some mutable reference to the inner value if it is of type `T`, or
302 /// `None` if it isn't.
307 /// use std::any::Any;
309 /// fn modify_if_u32(s: &mut dyn Any) {
310 /// if let Some(num) = s.downcast_mut::<u32>() {
315 /// let mut x = 10u32;
316 /// let mut s = "starlord".to_string();
318 /// modify_if_u32(&mut x);
319 /// modify_if_u32(&mut s);
321 /// assert_eq!(x, 42);
322 /// assert_eq!(&s, "starlord");
324 #[stable(feature = "rust1", since = "1.0.0")]
326 pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
328 // SAFETY: just checked whether we are pointing to the correct type, and we can rely on
329 // that check for memory safety because we have implemented Any for all types; no other
330 // impls can exist as they would conflict with our impl.
331 unsafe { Some(self.downcast_mut_unchecked()) }
337 /// Returns a reference to the inner value as type `dyn T`.
342 /// #![feature(downcast_unchecked)]
344 /// use std::any::Any;
346 /// let x: Box<dyn Any> = Box::new(1_usize);
349 /// assert_eq!(*x.downcast_ref_unchecked::<usize>(), 1);
355 /// The contained value must be of type `T`. Calling this method
356 /// with the incorrect type is *undefined behavior*.
357 #[unstable(feature = "downcast_unchecked", issue = "90850")]
359 pub unsafe fn downcast_ref_unchecked<T: Any>(&self) -> &T {
360 debug_assert!(self.is::<T>());
361 // SAFETY: caller guarantees that T is the correct type
362 unsafe { &*(self as *const dyn Any as *const T) }
365 /// Returns a mutable reference to the inner value as type `dyn T`.
370 /// #![feature(downcast_unchecked)]
372 /// use std::any::Any;
374 /// let mut x: Box<dyn Any> = Box::new(1_usize);
377 /// *x.downcast_mut_unchecked::<usize>() += 1;
380 /// assert_eq!(*x.downcast_ref::<usize>().unwrap(), 2);
385 /// The contained value must be of type `T`. Calling this method
386 /// with the incorrect type is *undefined behavior*.
387 #[unstable(feature = "downcast_unchecked", issue = "90850")]
389 pub unsafe fn downcast_mut_unchecked<T: Any>(&mut self) -> &mut T {
390 debug_assert!(self.is::<T>());
391 // SAFETY: caller guarantees that T is the correct type
392 unsafe { &mut *(self as *mut dyn Any as *mut T) }
396 impl dyn Any + Send {
397 /// Forwards to the method defined on the type `dyn Any`.
402 /// use std::any::Any;
404 /// fn is_string(s: &(dyn Any + Send)) {
405 /// if s.is::<String>() {
406 /// println!("It's a string!");
408 /// println!("Not a string...");
413 /// is_string(&"cookie monster".to_string());
415 #[stable(feature = "rust1", since = "1.0.0")]
417 pub fn is<T: Any>(&self) -> bool {
418 <dyn Any>::is::<T>(self)
421 /// Forwards to the method defined on the type `dyn Any`.
426 /// use std::any::Any;
428 /// fn print_if_string(s: &(dyn Any + Send)) {
429 /// if let Some(string) = s.downcast_ref::<String>() {
430 /// println!("It's a string({}): '{}'", string.len(), string);
432 /// println!("Not a string...");
436 /// print_if_string(&0);
437 /// print_if_string(&"cookie monster".to_string());
439 #[stable(feature = "rust1", since = "1.0.0")]
441 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
442 <dyn Any>::downcast_ref::<T>(self)
445 /// Forwards to the method defined on the type `dyn Any`.
450 /// use std::any::Any;
452 /// fn modify_if_u32(s: &mut (dyn Any + Send)) {
453 /// if let Some(num) = s.downcast_mut::<u32>() {
458 /// let mut x = 10u32;
459 /// let mut s = "starlord".to_string();
461 /// modify_if_u32(&mut x);
462 /// modify_if_u32(&mut s);
464 /// assert_eq!(x, 42);
465 /// assert_eq!(&s, "starlord");
467 #[stable(feature = "rust1", since = "1.0.0")]
469 pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
470 <dyn Any>::downcast_mut::<T>(self)
473 /// Forwards to the method defined on the type `dyn Any`.
478 /// #![feature(downcast_unchecked)]
480 /// use std::any::Any;
482 /// let x: Box<dyn Any> = Box::new(1_usize);
485 /// assert_eq!(*x.downcast_ref_unchecked::<usize>(), 1);
491 /// Same as the method on the type `dyn Any`.
492 #[unstable(feature = "downcast_unchecked", issue = "90850")]
494 pub unsafe fn downcast_ref_unchecked<T: Any>(&self) -> &T {
495 // SAFETY: guaranteed by caller
496 unsafe { <dyn Any>::downcast_ref_unchecked::<T>(self) }
499 /// Forwards to the method defined on the type `dyn Any`.
504 /// #![feature(downcast_unchecked)]
506 /// use std::any::Any;
508 /// let mut x: Box<dyn Any> = Box::new(1_usize);
511 /// *x.downcast_mut_unchecked::<usize>() += 1;
514 /// assert_eq!(*x.downcast_ref::<usize>().unwrap(), 2);
519 /// Same as the method on the type `dyn Any`.
520 #[unstable(feature = "downcast_unchecked", issue = "90850")]
522 pub unsafe fn downcast_mut_unchecked<T: Any>(&mut self) -> &mut T {
523 // SAFETY: guaranteed by caller
524 unsafe { <dyn Any>::downcast_mut_unchecked::<T>(self) }
528 impl dyn Any + Send + Sync {
529 /// Forwards to the method defined on the type `Any`.
534 /// use std::any::Any;
536 /// fn is_string(s: &(dyn Any + Send + Sync)) {
537 /// if s.is::<String>() {
538 /// println!("It's a string!");
540 /// println!("Not a string...");
545 /// is_string(&"cookie monster".to_string());
547 #[stable(feature = "any_send_sync_methods", since = "1.28.0")]
549 pub fn is<T: Any>(&self) -> bool {
550 <dyn Any>::is::<T>(self)
553 /// Forwards to the method defined on the type `Any`.
558 /// use std::any::Any;
560 /// fn print_if_string(s: &(dyn Any + Send + Sync)) {
561 /// if let Some(string) = s.downcast_ref::<String>() {
562 /// println!("It's a string({}): '{}'", string.len(), string);
564 /// println!("Not a string...");
568 /// print_if_string(&0);
569 /// print_if_string(&"cookie monster".to_string());
571 #[stable(feature = "any_send_sync_methods", since = "1.28.0")]
573 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
574 <dyn Any>::downcast_ref::<T>(self)
577 /// Forwards to the method defined on the type `Any`.
582 /// use std::any::Any;
584 /// fn modify_if_u32(s: &mut (dyn Any + Send + Sync)) {
585 /// if let Some(num) = s.downcast_mut::<u32>() {
590 /// let mut x = 10u32;
591 /// let mut s = "starlord".to_string();
593 /// modify_if_u32(&mut x);
594 /// modify_if_u32(&mut s);
596 /// assert_eq!(x, 42);
597 /// assert_eq!(&s, "starlord");
599 #[stable(feature = "any_send_sync_methods", since = "1.28.0")]
601 pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
602 <dyn Any>::downcast_mut::<T>(self)
605 /// Forwards to the method defined on the type `Any`.
610 /// #![feature(downcast_unchecked)]
612 /// use std::any::Any;
614 /// let x: Box<dyn Any> = Box::new(1_usize);
617 /// assert_eq!(*x.downcast_ref_unchecked::<usize>(), 1);
620 #[unstable(feature = "downcast_unchecked", issue = "90850")]
622 pub unsafe fn downcast_ref_unchecked<T: Any>(&self) -> &T {
623 // SAFETY: guaranteed by caller
624 unsafe { <dyn Any>::downcast_ref_unchecked::<T>(self) }
627 /// Forwards to the method defined on the type `Any`.
632 /// #![feature(downcast_unchecked)]
634 /// use std::any::Any;
636 /// let mut x: Box<dyn Any> = Box::new(1_usize);
639 /// *x.downcast_mut_unchecked::<usize>() += 1;
642 /// assert_eq!(*x.downcast_ref::<usize>().unwrap(), 2);
644 #[unstable(feature = "downcast_unchecked", issue = "90850")]
646 pub unsafe fn downcast_mut_unchecked<T: Any>(&mut self) -> &mut T {
647 // SAFETY: guaranteed by caller
648 unsafe { <dyn Any>::downcast_mut_unchecked::<T>(self) }
652 ///////////////////////////////////////////////////////////////////////////////
653 // TypeID and its methods
654 ///////////////////////////////////////////////////////////////////////////////
656 /// A `TypeId` represents a globally unique identifier for a type.
658 /// Each `TypeId` is an opaque object which does not allow inspection of what's
659 /// inside but does allow basic operations such as cloning, comparison,
660 /// printing, and showing.
662 /// A `TypeId` is currently only available for types which ascribe to `'static`,
663 /// but this limitation may be removed in the future.
665 /// While `TypeId` implements `Hash`, `PartialOrd`, and `Ord`, it is worth
666 /// noting that the hashes and ordering will vary between Rust releases. Beware
667 /// of relying on them inside of your code!
668 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
669 #[stable(feature = "rust1", since = "1.0.0")]
675 /// Returns the `TypeId` of the type this generic function has been
676 /// instantiated with.
681 /// use std::any::{Any, TypeId};
683 /// fn is_string<T: ?Sized + Any>(_s: &T) -> bool {
684 /// TypeId::of::<String>() == TypeId::of::<T>()
687 /// assert_eq!(is_string(&0), false);
688 /// assert_eq!(is_string(&"cookie monster".to_string()), true);
691 #[stable(feature = "rust1", since = "1.0.0")]
692 #[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
693 pub const fn of<T: ?Sized + 'static>() -> TypeId {
694 TypeId { t: intrinsics::type_id::<T>() }
698 /// Returns the name of a type as a string slice.
702 /// This is intended for diagnostic use. The exact contents and format of the
703 /// string returned are not specified, other than being a best-effort
704 /// description of the type. For example, amongst the strings
705 /// that `type_name::<Option<String>>()` might return are `"Option<String>"` and
706 /// `"std::option::Option<std::string::String>"`.
708 /// The returned string must not be considered to be a unique identifier of a
709 /// type as multiple types may map to the same type name. Similarly, there is no
710 /// guarantee that all parts of a type will appear in the returned string: for
711 /// example, lifetime specifiers are currently not included. In addition, the
712 /// output may change between versions of the compiler.
714 /// The current implementation uses the same infrastructure as compiler
715 /// diagnostics and debuginfo, but this is not guaranteed.
721 /// std::any::type_name::<Option<String>>(),
722 /// "core::option::Option<alloc::string::String>",
726 #[stable(feature = "type_name", since = "1.38.0")]
727 #[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
728 pub const fn type_name<T: ?Sized>() -> &'static str {
729 intrinsics::type_name::<T>()
732 /// Returns the name of the type of the pointed-to value as a string slice.
733 /// This is the same as `type_name::<T>()`, but can be used where the type of a
734 /// variable is not easily available.
738 /// This is intended for diagnostic use. The exact contents and format of the
739 /// string are not specified, other than being a best-effort description of the
740 /// type. For example, `type_name_of_val::<Option<String>>(None)` could return
741 /// `"Option<String>"` or `"std::option::Option<std::string::String>"`, but not
742 /// `"foobar"`. In addition, the output may change between versions of the
745 /// This function does not resolve trait objects,
746 /// meaning that `type_name_of_val(&7u32 as &dyn Debug)`
747 /// may return `"dyn Debug"`, but not `"u32"`.
749 /// The type name should not be considered a unique identifier of a type;
750 /// multiple types may share the same type name.
752 /// The current implementation uses the same infrastructure as compiler
753 /// diagnostics and debuginfo, but this is not guaranteed.
757 /// Prints the default integer and float types.
760 /// #![feature(type_name_of_val)]
761 /// use std::any::type_name_of_val;
764 /// println!("{}", type_name_of_val(&x));
766 /// println!("{}", type_name_of_val(&y));
769 #[unstable(feature = "type_name_of_val", issue = "66359")]
770 #[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
771 pub const fn type_name_of_val<T: ?Sized>(_val: &T) -> &'static str {
775 ///////////////////////////////////////////////////////////////////////////////
777 ///////////////////////////////////////////////////////////////////////////////
779 /// Trait implemented by a type which can dynamically provide values based on type.
780 #[unstable(feature = "provide_any", issue = "96024")]
782 /// Data providers should implement this method to provide *all* values they are able to
783 /// provide by using `demand`.
785 /// Note that the `provide_*` methods on `Demand` have short-circuit semantics: if an earlier
786 /// method has successfully provided a value, then later methods will not get an opportunity to
791 /// Provides a reference to a field with type `String` as a `&str`, and a value of
795 /// # #![feature(provide_any)]
796 /// use std::any::{Provider, Demand};
797 /// # struct SomeConcreteType { field: String, num_field: i32 }
799 /// impl Provider for SomeConcreteType {
800 /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
801 /// demand.provide_ref::<str>(&self.field)
802 /// .provide_value::<i32, _>(|| self.num_field);
806 #[unstable(feature = "provide_any", issue = "96024")]
807 fn provide<'a>(&'a self, demand: &mut Demand<'a>);
810 /// Request a value from the `Provider`.
814 /// Get a string value from a provider.
817 /// # #![feature(provide_any)]
818 /// use std::any::{Provider, request_value};
820 /// fn get_string<P: Provider>(provider: &P) -> String {
821 /// request_value::<String, _>(provider).unwrap()
824 #[unstable(feature = "provide_any", issue = "96024")]
825 pub fn request_value<'a, T, P>(provider: &'a P) -> Option<T>
828 P: Provider + ?Sized,
830 request_by_type_tag::<'a, tags::Value<T>, P>(provider)
833 /// Request a reference from the `Provider`.
837 /// Get a string reference from a provider.
840 /// # #![feature(provide_any)]
841 /// use std::any::{Provider, request_ref};
843 /// fn get_str<P: Provider>(provider: &P) -> &str {
844 /// request_ref::<str, _>(provider).unwrap()
847 #[unstable(feature = "provide_any", issue = "96024")]
848 pub fn request_ref<'a, T, P>(provider: &'a P) -> Option<&'a T>
851 P: Provider + ?Sized,
853 request_by_type_tag::<'a, tags::Ref<tags::MaybeSizedValue<T>>, P>(provider)
856 /// Request a specific value by tag from the `Provider`.
857 fn request_by_type_tag<'a, I, P>(provider: &'a P) -> Option<I::Reified>
860 P: Provider + ?Sized,
862 let mut tagged = TaggedOption::<'a, I>(None);
863 provider.provide(tagged.as_demand());
867 ///////////////////////////////////////////////////////////////////////////////
868 // Demand and its methods
869 ///////////////////////////////////////////////////////////////////////////////
871 /// A helper object for providing data by type.
873 /// A data provider provides values by calling this type's provide methods.
874 #[unstable(feature = "provide_any", issue = "96024")]
876 pub struct Demand<'a>(dyn Erased<'a> + 'a);
878 impl<'a> Demand<'a> {
879 /// Create a new `&mut Demand` from a `&mut dyn Erased` trait object.
880 fn new<'b>(erased: &'b mut (dyn Erased<'a> + 'a)) -> &'b mut Demand<'a> {
881 // SAFETY: transmuting `&mut (dyn Erased<'a> + 'a)` to `&mut Demand<'a>` is safe since
882 // `Demand` is repr(transparent).
883 unsafe { &mut *(erased as *mut dyn Erased<'a> as *mut Demand<'a>) }
886 /// Provide a value or other type with only static lifetimes.
890 /// Provides a `String` by cloning.
893 /// # #![feature(provide_any)]
894 /// use std::any::{Provider, Demand};
895 /// # struct SomeConcreteType { field: String }
897 /// impl Provider for SomeConcreteType {
898 /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
899 /// demand.provide_value::<String, _>(|| self.field.clone());
903 #[unstable(feature = "provide_any", issue = "96024")]
904 pub fn provide_value<T, F>(&mut self, fulfil: F) -> &mut Self
909 self.provide_with::<tags::Value<T>, F>(fulfil)
912 /// Provide a reference, note that the referee type must be bounded by `'static`,
913 /// but may be unsized.
917 /// Provides a reference to a field as a `&str`.
920 /// # #![feature(provide_any)]
921 /// use std::any::{Provider, Demand};
922 /// # struct SomeConcreteType { field: String }
924 /// impl Provider for SomeConcreteType {
925 /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
926 /// demand.provide_ref::<str>(&self.field);
930 #[unstable(feature = "provide_any", issue = "96024")]
931 pub fn provide_ref<T: ?Sized + 'static>(&mut self, value: &'a T) -> &mut Self {
932 self.provide::<tags::Ref<tags::MaybeSizedValue<T>>>(value)
935 /// Provide a value with the given `Type` tag.
936 fn provide<I>(&mut self, value: I::Reified) -> &mut Self
940 if let Some(res @ TaggedOption(None)) = self.0.downcast_mut::<I>() {
946 /// Provide a value with the given `Type` tag, using a closure to prevent unnecessary work.
947 fn provide_with<I, F>(&mut self, fulfil: F) -> &mut Self
950 F: FnOnce() -> I::Reified,
952 if let Some(res @ TaggedOption(None)) = self.0.downcast_mut::<I>() {
953 res.0 = Some(fulfil());
959 #[unstable(feature = "provide_any", issue = "96024")]
960 impl<'a> fmt::Debug for Demand<'a> {
961 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
962 f.debug_struct("Demand").finish_non_exhaustive()
966 ///////////////////////////////////////////////////////////////////////////////
968 ///////////////////////////////////////////////////////////////////////////////
971 //! Type tags are used to identify a type using a separate value. This module includes type tags
972 //! for some very common types.
974 //! Currently type tags are not exposed to the user. But in the future, if you want to use the
975 //! Provider API with more complex types (typically those including lifetime parameters), you
976 //! will need to write your own tags.
978 use crate::marker::PhantomData;
980 /// This trait is implemented by specific tag types in order to allow
981 /// describing a type which can be requested for a given lifetime `'a`.
983 /// A few example implementations for type-driven tags can be found in this
984 /// module, although crates may also implement their own tags for more
985 /// complex types with internal lifetimes.
986 pub trait Type<'a>: Sized + 'static {
987 /// The type of values which may be tagged by this tag for the given
992 /// Similar to the [`Type`] trait, but represents a type which may be unsized (i.e., has a
993 /// `?Sized` bound). E.g., `str`.
994 pub trait MaybeSizedType<'a>: Sized + 'static {
995 type Reified: 'a + ?Sized;
998 impl<'a, T: Type<'a>> MaybeSizedType<'a> for T {
999 type Reified = T::Reified;
1002 /// Type-based tag for types bounded by `'static`, i.e., with no borrowed elements.
1004 pub struct Value<T: 'static>(PhantomData<T>);
1006 impl<'a, T: 'static> Type<'a> for Value<T> {
1010 /// Type-based tag similar to [`Value`] but which may be unsized (i.e., has a `?Sized` bound).
1012 pub struct MaybeSizedValue<T: ?Sized + 'static>(PhantomData<T>);
1014 impl<'a, T: ?Sized + 'static> MaybeSizedType<'a> for MaybeSizedValue<T> {
1018 /// Type-based tag for reference types (`&'a T`, where T is represented by
1019 /// `<I as MaybeSizedType<'a>>::Reified`.
1021 pub struct Ref<I>(PhantomData<I>);
1023 impl<'a, I: MaybeSizedType<'a>> Type<'a> for Ref<I> {
1024 type Reified = &'a I::Reified;
1028 /// An `Option` with a type tag `I`.
1030 /// Since this struct implements `Erased`, the type can be erased to make a dynamically typed
1031 /// option. The type can be checked dynamically using `Erased::tag_id` and since this is statically
1032 /// checked for the concrete type, there is some degree of type safety.
1033 #[repr(transparent)]
1034 struct TaggedOption<'a, I: tags::Type<'a>>(Option<I::Reified>);
1036 impl<'a, I: tags::Type<'a>> TaggedOption<'a, I> {
1037 fn as_demand(&mut self) -> &mut Demand<'a> {
1038 Demand::new(self as &mut (dyn Erased<'a> + 'a))
1042 /// Represents a type-erased but identifiable object.
1044 /// This trait is exclusively implemented by the `TaggedOption` type.
1045 unsafe trait Erased<'a>: 'a {
1046 /// The `TypeId` of the erased type.
1047 fn tag_id(&self) -> TypeId;
1050 unsafe impl<'a, I: tags::Type<'a>> Erased<'a> for TaggedOption<'a, I> {
1051 fn tag_id(&self) -> TypeId {
1056 #[unstable(feature = "provide_any", issue = "96024")]
1057 impl<'a> dyn Erased<'a> + 'a {
1058 /// Returns some reference to the dynamic value if it is tagged with `I`,
1059 /// or `None` otherwise.
1061 fn downcast_mut<I>(&mut self) -> Option<&mut TaggedOption<'a, I>>
1065 if self.tag_id() == TypeId::of::<I>() {
1066 // SAFETY: Just checked whether we're pointing to an I.
1067 Some(unsafe { &mut *(self as *mut Self).cast::<TaggedOption<'a, I>>() })