]> git.proxmox.com Git - rustc.git/blame - library/core/src/any.rs
New upstream version 1.72.1+dfsg1
[rustc.git] / library / core / src / any.rs
CommitLineData
f2b60f7d 1//! Utilities for dynamic typing or type reflection.
923072b8
FG
2//!
3//! # `Any` and `TypeId`
1a4d82fc
JJ
4//!
5//! `Any` itself can be used to get a `TypeId`, and has more features when used
e74abb32
XL
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
e9174d1e 9//! is also the `downcast_mut` method, for getting a mutable reference to the
e74abb32 10//! inner value. `Box<dyn Any>` adds the `downcast` method, which attempts to
9cc50fc6 11//! convert to a `Box<T>`. See the [`Box`] documentation for the full details.
1a4d82fc 12//!
e74abb32 13//! Note that `&dyn Any` is limited to testing whether a value is of a specified
1a4d82fc
JJ
14//! concrete type, and cannot be used to test whether a type implements a trait.
15//!
54a0048b 16//! [`Box`]: ../../std/boxed/struct.Box.html
9cc50fc6 17//!
5869c6ff
XL
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//!
923072b8 41//! ## Examples
1a4d82fc
JJ
42//!
43//! Consider a situation where we want to log out a value passed to a function.
85aaf69f 44//! We know the value we're working on implements Debug, but we don't know its
9fa01778 45//! concrete type. We want to give special treatment to certain types: in this
1a4d82fc
JJ
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
85aaf69f 51//! use std::fmt::Debug;
1a4d82fc
JJ
52//! use std::any::Any;
53//!
85aaf69f
SL
54//! // Logger function for any type that implements Debug.
55//! fn log<T: Any + Debug>(value: &T) {
a1dfa0c6 56//! let value_any = value as &dyn Any;
1a4d82fc 57//!
9fa01778 58//! // Try to convert our value to a `String`. If successful, we want to
9ffffee4 59//! // output the `String`'s length as well as its value. If not, it's a
1a4d82fc
JJ
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 => {
5e7ed085 66//! println!("{value:?}");
1a4d82fc
JJ
67//! }
68//! }
69//! }
70//!
71//! // This function wants to log its parameter out prior to doing work with it.
c34b1796 72//! fn do_work<T: Any + Debug>(value: &T) {
1a4d82fc
JJ
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//! ```
923072b8
FG
85//!
86//! # `Provider` and `Demand`
87//!
88//! `Provider` and the associated APIs support generic, type-driven access to data, and a mechanism
89//! for implementers to provide such data. The key parts of the interface are the `Provider`
90//! trait for objects which can provide data, and the [`request_value`] and [`request_ref`]
91//! functions for requesting data from an object which implements `Provider`. Generally, end users
92//! should not call `request_*` directly, they are helper functions for intermediate implementers
93//! to use to implement a user-facing interface. This is purely for the sake of ergonomics, there is
94//! no safety concern here; intermediate implementers can typically support methods rather than
95//! free functions and use more specific names.
96//!
97//! Typically, a data provider is a trait object of a trait which extends `Provider`. A user will
98//! request data from a trait object by specifying the type of the data.
99//!
100//! ## Data flow
101//!
102//! * A user requests an object of a specific type, which is delegated to `request_value` or
103//! `request_ref`
104//! * `request_*` creates a `Demand` object and passes it to `Provider::provide`
105//! * The data provider's implementation of `Provider::provide` tries providing values of
106//! different types using `Demand::provide_*`. If the type matches the type requested by
107//! the user, the value will be stored in the `Demand` object.
108//! * `request_*` unpacks the `Demand` object and returns any stored value to the user.
109//!
110//! ## Examples
111//!
112//! ```
113//! # #![feature(provide_any)]
114//! use std::any::{Provider, Demand, request_ref};
115//!
116//! // Definition of MyTrait, a data provider.
117//! trait MyTrait: Provider {
118//! // ...
119//! }
120//!
121//! // Methods on `MyTrait` trait objects.
122//! impl dyn MyTrait + '_ {
123//! /// Get a reference to a field of the implementing struct.
124//! pub fn get_context_by_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
064997fb 125//! request_ref::<T>(self)
923072b8
FG
126//! }
127//! }
128//!
129//! // Downstream implementation of `MyTrait` and `Provider`.
130//! # struct SomeConcreteType { some_string: String }
131//! impl MyTrait for SomeConcreteType {
132//! // ...
133//! }
134//!
135//! impl Provider for SomeConcreteType {
136//! fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
137//! // Provide a string reference. We could provide multiple values with
138//! // different types here.
139//! demand.provide_ref::<String>(&self.some_string);
140//! }
141//! }
142//!
143//! // Downstream usage of `MyTrait`.
144//! fn use_my_trait(obj: &dyn MyTrait) {
145//! // Request a &String from obj.
146//! let _ = obj.get_context_by_ref::<String>().unwrap();
147//! }
148//! ```
149//!
150//! In this example, if the concrete type of `obj` in `use_my_trait` is `SomeConcreteType`, then
9c376795 151//! the `get_context_by_ref` call will return a reference to `obj.some_string` with type `&String`.
1a4d82fc 152
85aaf69f 153#![stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 154
48663c56 155use crate::fmt;
fe692bf9 156use crate::hash;
48663c56 157use crate::intrinsics;
1a4d82fc
JJ
158
159///////////////////////////////////////////////////////////////////////////////
160// Any trait
161///////////////////////////////////////////////////////////////////////////////
162
60c5eb7d 163/// A trait to emulate dynamic typing.
1a4d82fc 164///
3157f602 165/// Most types implement `Any`. However, any type which contains a non-`'static` reference does not.
9346a6ac 166/// See the [module-level documentation][mod] for more details.
c34b1796 167///
3dfed10e 168/// [mod]: crate::any
dfeec247
XL
169// This trait is not unsafe, though we rely on the specifics of it's sole impl's
170// `type_id` function in unsafe code (e.g., `downcast`). Normally, that would be
171// a problem, but because the only impl of `Any` is a blanket implementation, no
172// other code can implement `Any`.
173//
174// We could plausibly make this trait unsafe -- it would not cause breakage,
175// since we control all the implementations -- but we choose not to as that's
176// both not really necessary and may confuse users about the distinction of
177// unsafe traits and unsafe methods (i.e., `type_id` would still be safe to call,
178// but we would likely want to indicate as such in documentation).
85aaf69f 179#[stable(feature = "rust1", since = "1.0.0")]
136023e0 180#[cfg_attr(not(test), rustc_diagnostic_item = "Any")]
9e0c209e 181pub trait Any: 'static {
9346a6ac 182 /// Gets the `TypeId` of `self`.
5bcae85e
SL
183 ///
184 /// # Examples
185 ///
186 /// ```
5bcae85e
SL
187 /// use std::any::{Any, TypeId};
188 ///
a1dfa0c6 189 /// fn is_string(s: &dyn Any) -> bool {
9fa01778 190 /// TypeId::of::<String>() == s.type_id()
5bcae85e
SL
191 /// }
192 ///
e74abb32
XL
193 /// assert_eq!(is_string(&0), false);
194 /// assert_eq!(is_string(&"cookie monster".to_string()), true);
5bcae85e 195 /// ```
9fa01778
XL
196 #[stable(feature = "get_type_id", since = "1.34.0")]
197 fn type_id(&self) -> TypeId;
1a4d82fc
JJ
198}
199
92a42be0 200#[stable(feature = "rust1", since = "1.0.0")]
dfeec247
XL
201impl<T: 'static + ?Sized> Any for T {
202 fn type_id(&self) -> TypeId {
203 TypeId::of::<T>()
204 }
1a4d82fc
JJ
205}
206
207///////////////////////////////////////////////////////////////////////////////
208// Extension methods for Any trait objects.
1a4d82fc
JJ
209///////////////////////////////////////////////////////////////////////////////
210
c34b1796 211#[stable(feature = "rust1", since = "1.0.0")]
8faf50e0 212impl fmt::Debug for dyn Any {
48663c56 213 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
cdc7bbd5 214 f.debug_struct("Any").finish_non_exhaustive()
c34b1796
AL
215 }
216}
217
0731742a 218// Ensure that the result of e.g., joining a thread can be printed and
9346a6ac
AL
219// hence used with `unwrap`. May eventually no longer be needed if
220// dispatch works with upcasting.
221#[stable(feature = "rust1", since = "1.0.0")]
8faf50e0 222impl fmt::Debug for dyn Any + Send {
48663c56 223 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
cdc7bbd5 224 f.debug_struct("Any").finish_non_exhaustive()
9346a6ac
AL
225 }
226}
227
94b46f34 228#[stable(feature = "any_send_sync_methods", since = "1.28.0")]
8faf50e0 229impl fmt::Debug for dyn Any + Send + Sync {
48663c56 230 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
cdc7bbd5 231 f.debug_struct("Any").finish_non_exhaustive()
94b46f34
XL
232 }
233}
234
8faf50e0 235impl dyn Any {
a2a8927a 236 /// Returns `true` if the inner type is the same as `T`.
5bcae85e
SL
237 ///
238 /// # Examples
239 ///
240 /// ```
241 /// use std::any::Any;
242 ///
a1dfa0c6 243 /// fn is_string(s: &dyn Any) {
5bcae85e
SL
244 /// if s.is::<String>() {
245 /// println!("It's a string!");
246 /// } else {
247 /// println!("Not a string...");
248 /// }
249 /// }
250 ///
e74abb32
XL
251 /// is_string(&0);
252 /// is_string(&"cookie monster".to_string());
5bcae85e 253 /// ```
85aaf69f 254 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 255 #[inline]
c34b1796 256 pub fn is<T: Any>(&self) -> bool {
e1599b0c 257 // Get `TypeId` of the type this function is instantiated with.
1a4d82fc
JJ
258 let t = TypeId::of::<T>();
259
ba9703b0 260 // Get `TypeId` of the type in the trait object (`self`).
9fa01778 261 let concrete = self.type_id();
1a4d82fc 262
e1599b0c 263 // Compare both `TypeId`s on equality.
9fa01778 264 t == concrete
1a4d82fc
JJ
265 }
266
a2a8927a 267 /// Returns some reference to the inner value if it is of type `T`, or
1a4d82fc 268 /// `None` if it isn't.
5bcae85e
SL
269 ///
270 /// # Examples
271 ///
272 /// ```
273 /// use std::any::Any;
274 ///
a1dfa0c6 275 /// fn print_if_string(s: &dyn Any) {
5bcae85e
SL
276 /// if let Some(string) = s.downcast_ref::<String>() {
277 /// println!("It's a string({}): '{}'", string.len(), string);
278 /// } else {
279 /// println!("Not a string...");
280 /// }
281 /// }
282 ///
e74abb32
XL
283 /// print_if_string(&0);
284 /// print_if_string(&"cookie monster".to_string());
5bcae85e 285 /// ```
85aaf69f 286 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 287 #[inline]
c34b1796 288 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
1a4d82fc 289 if self.is::<T>() {
74b04a01
XL
290 // SAFETY: just checked whether we are pointing to the correct type, and we can rely on
291 // that check for memory safety because we have implemented Any for all types; no other
292 // impls can exist as they would conflict with our impl.
a2a8927a 293 unsafe { Some(self.downcast_ref_unchecked()) }
1a4d82fc
JJ
294 } else {
295 None
296 }
297 }
298
a2a8927a 299 /// Returns some mutable reference to the inner value if it is of type `T`, or
1a4d82fc 300 /// `None` if it isn't.
5bcae85e
SL
301 ///
302 /// # Examples
303 ///
304 /// ```
305 /// use std::any::Any;
306 ///
a1dfa0c6 307 /// fn modify_if_u32(s: &mut dyn Any) {
5bcae85e
SL
308 /// if let Some(num) = s.downcast_mut::<u32>() {
309 /// *num = 42;
310 /// }
311 /// }
312 ///
e74abb32
XL
313 /// let mut x = 10u32;
314 /// let mut s = "starlord".to_string();
5bcae85e 315 ///
e74abb32
XL
316 /// modify_if_u32(&mut x);
317 /// modify_if_u32(&mut s);
5bcae85e 318 ///
e74abb32
XL
319 /// assert_eq!(x, 42);
320 /// assert_eq!(&s, "starlord");
5bcae85e 321 /// ```
85aaf69f 322 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 323 #[inline]
c34b1796 324 pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
1a4d82fc 325 if self.is::<T>() {
74b04a01
XL
326 // SAFETY: just checked whether we are pointing to the correct type, and we can rely on
327 // that check for memory safety because we have implemented Any for all types; no other
328 // impls can exist as they would conflict with our impl.
a2a8927a 329 unsafe { Some(self.downcast_mut_unchecked()) }
1a4d82fc
JJ
330 } else {
331 None
332 }
333 }
a2a8927a
XL
334
335 /// Returns a reference to the inner value as type `dyn T`.
336 ///
337 /// # Examples
338 ///
339 /// ```
340 /// #![feature(downcast_unchecked)]
341 ///
342 /// use std::any::Any;
343 ///
344 /// let x: Box<dyn Any> = Box::new(1_usize);
345 ///
346 /// unsafe {
347 /// assert_eq!(*x.downcast_ref_unchecked::<usize>(), 1);
348 /// }
349 /// ```
350 ///
351 /// # Safety
352 ///
353 /// The contained value must be of type `T`. Calling this method
354 /// with the incorrect type is *undefined behavior*.
355 #[unstable(feature = "downcast_unchecked", issue = "90850")]
356 #[inline]
357 pub unsafe fn downcast_ref_unchecked<T: Any>(&self) -> &T {
358 debug_assert!(self.is::<T>());
359 // SAFETY: caller guarantees that T is the correct type
360 unsafe { &*(self as *const dyn Any as *const T) }
361 }
362
363 /// Returns a mutable reference to the inner value as type `dyn T`.
364 ///
365 /// # Examples
366 ///
367 /// ```
368 /// #![feature(downcast_unchecked)]
369 ///
370 /// use std::any::Any;
371 ///
372 /// let mut x: Box<dyn Any> = Box::new(1_usize);
373 ///
374 /// unsafe {
375 /// *x.downcast_mut_unchecked::<usize>() += 1;
376 /// }
377 ///
378 /// assert_eq!(*x.downcast_ref::<usize>().unwrap(), 2);
379 /// ```
380 ///
381 /// # Safety
382 ///
383 /// The contained value must be of type `T`. Calling this method
384 /// with the incorrect type is *undefined behavior*.
385 #[unstable(feature = "downcast_unchecked", issue = "90850")]
386 #[inline]
387 pub unsafe fn downcast_mut_unchecked<T: Any>(&mut self) -> &mut T {
388 debug_assert!(self.is::<T>());
389 // SAFETY: caller guarantees that T is the correct type
390 unsafe { &mut *(self as *mut dyn Any as *mut T) }
391 }
1a4d82fc 392}
85aaf69f 393
dfeec247 394impl dyn Any + Send {
a2a8927a 395 /// Forwards to the method defined on the type `dyn Any`.
5bcae85e
SL
396 ///
397 /// # Examples
398 ///
399 /// ```
400 /// use std::any::Any;
401 ///
a1dfa0c6 402 /// fn is_string(s: &(dyn Any + Send)) {
5bcae85e
SL
403 /// if s.is::<String>() {
404 /// println!("It's a string!");
405 /// } else {
406 /// println!("Not a string...");
407 /// }
408 /// }
409 ///
e74abb32
XL
410 /// is_string(&0);
411 /// is_string(&"cookie monster".to_string());
5bcae85e 412 /// ```
c34b1796
AL
413 #[stable(feature = "rust1", since = "1.0.0")]
414 #[inline]
415 pub fn is<T: Any>(&self) -> bool {
6a06907d 416 <dyn Any>::is::<T>(self)
c34b1796
AL
417 }
418
a2a8927a 419 /// Forwards to the method defined on the type `dyn Any`.
5bcae85e
SL
420 ///
421 /// # Examples
422 ///
423 /// ```
424 /// use std::any::Any;
425 ///
a1dfa0c6 426 /// fn print_if_string(s: &(dyn Any + Send)) {
5bcae85e
SL
427 /// if let Some(string) = s.downcast_ref::<String>() {
428 /// println!("It's a string({}): '{}'", string.len(), string);
429 /// } else {
430 /// println!("Not a string...");
431 /// }
432 /// }
433 ///
e74abb32
XL
434 /// print_if_string(&0);
435 /// print_if_string(&"cookie monster".to_string());
5bcae85e 436 /// ```
c34b1796
AL
437 #[stable(feature = "rust1", since = "1.0.0")]
438 #[inline]
439 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
6a06907d 440 <dyn Any>::downcast_ref::<T>(self)
c34b1796
AL
441 }
442
a2a8927a 443 /// Forwards to the method defined on the type `dyn Any`.
5bcae85e
SL
444 ///
445 /// # Examples
446 ///
447 /// ```
448 /// use std::any::Any;
449 ///
a1dfa0c6 450 /// fn modify_if_u32(s: &mut (dyn Any + Send)) {
5bcae85e
SL
451 /// if let Some(num) = s.downcast_mut::<u32>() {
452 /// *num = 42;
453 /// }
454 /// }
455 ///
e74abb32
XL
456 /// let mut x = 10u32;
457 /// let mut s = "starlord".to_string();
5bcae85e 458 ///
e74abb32
XL
459 /// modify_if_u32(&mut x);
460 /// modify_if_u32(&mut s);
5bcae85e 461 ///
e74abb32
XL
462 /// assert_eq!(x, 42);
463 /// assert_eq!(&s, "starlord");
5bcae85e 464 /// ```
c34b1796
AL
465 #[stable(feature = "rust1", since = "1.0.0")]
466 #[inline]
467 pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
6a06907d 468 <dyn Any>::downcast_mut::<T>(self)
c34b1796 469 }
a2a8927a
XL
470
471 /// Forwards to the method defined on the type `dyn Any`.
472 ///
473 /// # Examples
474 ///
475 /// ```
476 /// #![feature(downcast_unchecked)]
477 ///
478 /// use std::any::Any;
479 ///
480 /// let x: Box<dyn Any> = Box::new(1_usize);
481 ///
482 /// unsafe {
483 /// assert_eq!(*x.downcast_ref_unchecked::<usize>(), 1);
484 /// }
485 /// ```
486 ///
487 /// # Safety
488 ///
489 /// Same as the method on the type `dyn Any`.
490 #[unstable(feature = "downcast_unchecked", issue = "90850")]
491 #[inline]
492 pub unsafe fn downcast_ref_unchecked<T: Any>(&self) -> &T {
493 // SAFETY: guaranteed by caller
494 unsafe { <dyn Any>::downcast_ref_unchecked::<T>(self) }
495 }
496
497 /// Forwards to the method defined on the type `dyn Any`.
498 ///
499 /// # Examples
500 ///
501 /// ```
502 /// #![feature(downcast_unchecked)]
503 ///
504 /// use std::any::Any;
505 ///
506 /// let mut x: Box<dyn Any> = Box::new(1_usize);
507 ///
508 /// unsafe {
509 /// *x.downcast_mut_unchecked::<usize>() += 1;
510 /// }
511 ///
512 /// assert_eq!(*x.downcast_ref::<usize>().unwrap(), 2);
513 /// ```
514 ///
515 /// # Safety
516 ///
517 /// Same as the method on the type `dyn Any`.
518 #[unstable(feature = "downcast_unchecked", issue = "90850")]
519 #[inline]
520 pub unsafe fn downcast_mut_unchecked<T: Any>(&mut self) -> &mut T {
521 // SAFETY: guaranteed by caller
522 unsafe { <dyn Any>::downcast_mut_unchecked::<T>(self) }
523 }
c34b1796
AL
524}
525
dfeec247 526impl dyn Any + Send + Sync {
94b46f34
XL
527 /// Forwards to the method defined on the type `Any`.
528 ///
529 /// # Examples
530 ///
531 /// ```
532 /// use std::any::Any;
533 ///
a1dfa0c6 534 /// fn is_string(s: &(dyn Any + Send + Sync)) {
94b46f34
XL
535 /// if s.is::<String>() {
536 /// println!("It's a string!");
537 /// } else {
538 /// println!("Not a string...");
539 /// }
540 /// }
541 ///
e74abb32
XL
542 /// is_string(&0);
543 /// is_string(&"cookie monster".to_string());
94b46f34
XL
544 /// ```
545 #[stable(feature = "any_send_sync_methods", since = "1.28.0")]
546 #[inline]
547 pub fn is<T: Any>(&self) -> bool {
6a06907d 548 <dyn Any>::is::<T>(self)
94b46f34
XL
549 }
550
551 /// Forwards to the method defined on the type `Any`.
552 ///
553 /// # Examples
554 ///
555 /// ```
556 /// use std::any::Any;
557 ///
a1dfa0c6 558 /// fn print_if_string(s: &(dyn Any + Send + Sync)) {
94b46f34
XL
559 /// if let Some(string) = s.downcast_ref::<String>() {
560 /// println!("It's a string({}): '{}'", string.len(), string);
561 /// } else {
562 /// println!("Not a string...");
563 /// }
564 /// }
565 ///
e74abb32
XL
566 /// print_if_string(&0);
567 /// print_if_string(&"cookie monster".to_string());
94b46f34
XL
568 /// ```
569 #[stable(feature = "any_send_sync_methods", since = "1.28.0")]
570 #[inline]
571 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
6a06907d 572 <dyn Any>::downcast_ref::<T>(self)
94b46f34
XL
573 }
574
575 /// Forwards to the method defined on the type `Any`.
576 ///
577 /// # Examples
578 ///
579 /// ```
580 /// use std::any::Any;
581 ///
a1dfa0c6 582 /// fn modify_if_u32(s: &mut (dyn Any + Send + Sync)) {
94b46f34
XL
583 /// if let Some(num) = s.downcast_mut::<u32>() {
584 /// *num = 42;
585 /// }
586 /// }
587 ///
e74abb32
XL
588 /// let mut x = 10u32;
589 /// let mut s = "starlord".to_string();
94b46f34 590 ///
e74abb32
XL
591 /// modify_if_u32(&mut x);
592 /// modify_if_u32(&mut s);
94b46f34 593 ///
e74abb32
XL
594 /// assert_eq!(x, 42);
595 /// assert_eq!(&s, "starlord");
94b46f34
XL
596 /// ```
597 #[stable(feature = "any_send_sync_methods", since = "1.28.0")]
598 #[inline]
599 pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
6a06907d 600 <dyn Any>::downcast_mut::<T>(self)
94b46f34 601 }
a2a8927a
XL
602
603 /// Forwards to the method defined on the type `Any`.
604 ///
605 /// # Examples
606 ///
607 /// ```
608 /// #![feature(downcast_unchecked)]
609 ///
610 /// use std::any::Any;
611 ///
612 /// let x: Box<dyn Any> = Box::new(1_usize);
613 ///
614 /// unsafe {
615 /// assert_eq!(*x.downcast_ref_unchecked::<usize>(), 1);
616 /// }
617 /// ```
618 #[unstable(feature = "downcast_unchecked", issue = "90850")]
619 #[inline]
620 pub unsafe fn downcast_ref_unchecked<T: Any>(&self) -> &T {
621 // SAFETY: guaranteed by caller
622 unsafe { <dyn Any>::downcast_ref_unchecked::<T>(self) }
623 }
624
625 /// Forwards to the method defined on the type `Any`.
626 ///
627 /// # Examples
628 ///
629 /// ```
630 /// #![feature(downcast_unchecked)]
631 ///
632 /// use std::any::Any;
633 ///
634 /// let mut x: Box<dyn Any> = Box::new(1_usize);
635 ///
636 /// unsafe {
637 /// *x.downcast_mut_unchecked::<usize>() += 1;
638 /// }
639 ///
640 /// assert_eq!(*x.downcast_ref::<usize>().unwrap(), 2);
641 /// ```
642 #[unstable(feature = "downcast_unchecked", issue = "90850")]
643 #[inline]
644 pub unsafe fn downcast_mut_unchecked<T: Any>(&mut self) -> &mut T {
645 // SAFETY: guaranteed by caller
646 unsafe { <dyn Any>::downcast_mut_unchecked::<T>(self) }
647 }
94b46f34 648}
c34b1796 649
85aaf69f
SL
650///////////////////////////////////////////////////////////////////////////////
651// TypeID and its methods
652///////////////////////////////////////////////////////////////////////////////
653
654/// A `TypeId` represents a globally unique identifier for a type.
655///
656/// Each `TypeId` is an opaque object which does not allow inspection of what's
657/// inside but does allow basic operations such as cloning, comparison,
658/// printing, and showing.
659///
660/// A `TypeId` is currently only available for types which ascribe to `'static`,
661/// but this limitation may be removed in the future.
8bb4bdeb
XL
662///
663/// While `TypeId` implements `Hash`, `PartialOrd`, and `Ord`, it is worth
664/// noting that the hashes and ordering will vary between Rust releases. Beware
8faf50e0 665/// of relying on them inside of your code!
fe692bf9 666#[derive(Clone, Copy, Debug, Eq, PartialOrd, Ord)]
85aaf69f
SL
667#[stable(feature = "rust1", since = "1.0.0")]
668pub struct TypeId {
fe692bf9 669 t: u128,
85aaf69f
SL
670}
671
49aad941
FG
672#[stable(feature = "rust1", since = "1.0.0")]
673impl PartialEq for TypeId {
674 #[inline]
675 fn eq(&self, other: &Self) -> bool {
676 self.t == other.t
677 }
678}
679
85aaf69f 680impl TypeId {
2c00a5a8
XL
681 /// Returns the `TypeId` of the type this generic function has been
682 /// instantiated with.
683 ///
684 /// # Examples
685 ///
686 /// ```
687 /// use std::any::{Any, TypeId};
688 ///
689 /// fn is_string<T: ?Sized + Any>(_s: &T) -> bool {
690 /// TypeId::of::<String>() == TypeId::of::<T>()
691 /// }
692 ///
e74abb32
XL
693 /// assert_eq!(is_string(&0), false);
694 /// assert_eq!(is_string(&"cookie monster".to_string()), true);
2c00a5a8 695 /// ```
3c0e092e 696 #[must_use]
2c00a5a8 697 #[stable(feature = "rust1", since = "1.0.0")]
6c58768f 698 #[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
2c00a5a8 699 pub const fn of<T: ?Sized + 'static>() -> TypeId {
fe692bf9
FG
700 #[cfg(bootstrap)]
701 let t = intrinsics::type_id::<T>() as u128;
702 #[cfg(not(bootstrap))]
703 let t: u128 = intrinsics::type_id::<T>();
704 TypeId { t }
705 }
706}
707
708#[stable(feature = "rust1", since = "1.0.0")]
709impl hash::Hash for TypeId {
710 #[inline]
711 fn hash<H: hash::Hasher>(&self, state: &mut H) {
712 // We only hash the lower 64 bits of our (128 bit) internal numeric ID,
713 // because:
714 // - The hashing algorithm which backs `TypeId` is expected to be
715 // unbiased and high quality, meaning further mixing would be somewhat
716 // redundant compared to choosing (the lower) 64 bits arbitrarily.
717 // - `Hasher::finish` returns a u64 anyway, so the extra entropy we'd
718 // get from hashing the full value would probably not be useful
719 // (especially given the previous point about the lower 64 bits being
720 // high quality on their own).
721 // - It is correct to do so -- only hashing a subset of `self` is still
722 // with an `Eq` implementation that considers the entire value, as
723 // ours does.
724 (self.t as u64).hash(state);
2c00a5a8 725 }
85aaf69f 726}
416331ca
XL
727
728/// Returns the name of a type as a string slice.
729///
730/// # Note
731///
732/// This is intended for diagnostic use. The exact contents and format of the
f9f354fc
XL
733/// string returned are not specified, other than being a best-effort
734/// description of the type. For example, amongst the strings
735/// that `type_name::<Option<String>>()` might return are `"Option<String>"` and
736/// `"std::option::Option<std::string::String>"`.
416331ca 737///
f9f354fc
XL
738/// The returned string must not be considered to be a unique identifier of a
739/// type as multiple types may map to the same type name. Similarly, there is no
740/// guarantee that all parts of a type will appear in the returned string: for
741/// example, lifetime specifiers are currently not included. In addition, the
742/// output may change between versions of the compiler.
416331ca
XL
743///
744/// The current implementation uses the same infrastructure as compiler
745/// diagnostics and debuginfo, but this is not guaranteed.
e74abb32 746///
60c5eb7d 747/// # Examples
e74abb32
XL
748///
749/// ```rust
750/// assert_eq!(
751/// std::any::type_name::<Option<String>>(),
752/// "core::option::Option<alloc::string::String>",
753/// );
754/// ```
3c0e092e 755#[must_use]
416331ca 756#[stable(feature = "type_name", since = "1.38.0")]
dfeec247 757#[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
416331ca 758pub const fn type_name<T: ?Sized>() -> &'static str {
416331ca
XL
759 intrinsics::type_name::<T>()
760}
60c5eb7d
XL
761
762/// Returns the name of the type of the pointed-to value as a string slice.
763/// This is the same as `type_name::<T>()`, but can be used where the type of a
764/// variable is not easily available.
765///
766/// # Note
767///
768/// This is intended for diagnostic use. The exact contents and format of the
769/// string are not specified, other than being a best-effort description of the
dfeec247 770/// type. For example, `type_name_of_val::<Option<String>>(None)` could return
60c5eb7d
XL
771/// `"Option<String>"` or `"std::option::Option<std::string::String>"`, but not
772/// `"foobar"`. In addition, the output may change between versions of the
773/// compiler.
774///
dfeec247
XL
775/// This function does not resolve trait objects,
776/// meaning that `type_name_of_val(&7u32 as &dyn Debug)`
777/// may return `"dyn Debug"`, but not `"u32"`.
778///
60c5eb7d
XL
779/// The type name should not be considered a unique identifier of a type;
780/// multiple types may share the same type name.
781///
782/// The current implementation uses the same infrastructure as compiler
783/// diagnostics and debuginfo, but this is not guaranteed.
784///
785/// # Examples
786///
787/// Prints the default integer and float types.
788///
789/// ```rust
790/// #![feature(type_name_of_val)]
791/// use std::any::type_name_of_val;
792///
793/// let x = 1;
794/// println!("{}", type_name_of_val(&x));
795/// let y = 1.0;
796/// println!("{}", type_name_of_val(&y));
797/// ```
3c0e092e 798#[must_use]
60c5eb7d 799#[unstable(feature = "type_name_of_val", issue = "66359")]
dfeec247
XL
800#[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
801pub const fn type_name_of_val<T: ?Sized>(_val: &T) -> &'static str {
60c5eb7d
XL
802 type_name::<T>()
803}
923072b8
FG
804
805///////////////////////////////////////////////////////////////////////////////
806// Provider trait
807///////////////////////////////////////////////////////////////////////////////
808
809/// Trait implemented by a type which can dynamically provide values based on type.
810#[unstable(feature = "provide_any", issue = "96024")]
811pub trait Provider {
812 /// Data providers should implement this method to provide *all* values they are able to
813 /// provide by using `demand`.
814 ///
815 /// Note that the `provide_*` methods on `Demand` have short-circuit semantics: if an earlier
816 /// method has successfully provided a value, then later methods will not get an opportunity to
817 /// provide.
818 ///
819 /// # Examples
820 ///
821 /// Provides a reference to a field with type `String` as a `&str`, and a value of
822 /// type `i32`.
823 ///
824 /// ```rust
825 /// # #![feature(provide_any)]
826 /// use std::any::{Provider, Demand};
827 /// # struct SomeConcreteType { field: String, num_field: i32 }
828 ///
829 /// impl Provider for SomeConcreteType {
830 /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
831 /// demand.provide_ref::<str>(&self.field)
f2b60f7d 832 /// .provide_value::<i32>(self.num_field);
923072b8
FG
833 /// }
834 /// }
835 /// ```
836 #[unstable(feature = "provide_any", issue = "96024")]
837 fn provide<'a>(&'a self, demand: &mut Demand<'a>);
838}
839
840/// Request a value from the `Provider`.
841///
842/// # Examples
843///
844/// Get a string value from a provider.
845///
846/// ```rust
847/// # #![feature(provide_any)]
848/// use std::any::{Provider, request_value};
849///
064997fb
FG
850/// fn get_string(provider: &impl Provider) -> String {
851/// request_value::<String>(provider).unwrap()
923072b8
FG
852/// }
853/// ```
854#[unstable(feature = "provide_any", issue = "96024")]
064997fb 855pub fn request_value<'a, T>(provider: &'a (impl Provider + ?Sized)) -> Option<T>
923072b8
FG
856where
857 T: 'static,
923072b8 858{
064997fb 859 request_by_type_tag::<'a, tags::Value<T>>(provider)
923072b8
FG
860}
861
862/// Request a reference from the `Provider`.
863///
864/// # Examples
865///
866/// Get a string reference from a provider.
867///
868/// ```rust
869/// # #![feature(provide_any)]
870/// use std::any::{Provider, request_ref};
871///
064997fb
FG
872/// fn get_str(provider: &impl Provider) -> &str {
873/// request_ref::<str>(provider).unwrap()
923072b8
FG
874/// }
875/// ```
876#[unstable(feature = "provide_any", issue = "96024")]
064997fb 877pub fn request_ref<'a, T>(provider: &'a (impl Provider + ?Sized)) -> Option<&'a T>
923072b8
FG
878where
879 T: 'static + ?Sized,
923072b8 880{
064997fb 881 request_by_type_tag::<'a, tags::Ref<tags::MaybeSizedValue<T>>>(provider)
923072b8
FG
882}
883
884/// Request a specific value by tag from the `Provider`.
064997fb 885fn request_by_type_tag<'a, I>(provider: &'a (impl Provider + ?Sized)) -> Option<I::Reified>
923072b8
FG
886where
887 I: tags::Type<'a>,
923072b8
FG
888{
889 let mut tagged = TaggedOption::<'a, I>(None);
890 provider.provide(tagged.as_demand());
891 tagged.0
892}
893
894///////////////////////////////////////////////////////////////////////////////
895// Demand and its methods
896///////////////////////////////////////////////////////////////////////////////
897
898/// A helper object for providing data by type.
899///
900/// A data provider provides values by calling this type's provide methods.
901#[unstable(feature = "provide_any", issue = "96024")]
49aad941 902#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435
923072b8
FG
903pub struct Demand<'a>(dyn Erased<'a> + 'a);
904
905impl<'a> Demand<'a> {
906 /// Create a new `&mut Demand` from a `&mut dyn Erased` trait object.
907 fn new<'b>(erased: &'b mut (dyn Erased<'a> + 'a)) -> &'b mut Demand<'a> {
908 // SAFETY: transmuting `&mut (dyn Erased<'a> + 'a)` to `&mut Demand<'a>` is safe since
909 // `Demand` is repr(transparent).
910 unsafe { &mut *(erased as *mut dyn Erased<'a> as *mut Demand<'a>) }
911 }
912
913 /// Provide a value or other type with only static lifetimes.
914 ///
915 /// # Examples
916 ///
f2b60f7d
FG
917 /// Provides an `u8`.
918 ///
919 /// ```rust
920 /// #![feature(provide_any)]
921 ///
922 /// use std::any::{Provider, Demand};
923 /// # struct SomeConcreteType { field: u8 }
924 ///
925 /// impl Provider for SomeConcreteType {
926 /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
927 /// demand.provide_value::<u8>(self.field);
928 /// }
929 /// }
930 /// ```
931 #[unstable(feature = "provide_any", issue = "96024")]
932 pub fn provide_value<T>(&mut self, value: T) -> &mut Self
933 where
934 T: 'static,
935 {
936 self.provide::<tags::Value<T>>(value)
937 }
938
939 /// Provide a value or other type with only static lifetimes computed using a closure.
940 ///
941 /// # Examples
942 ///
923072b8
FG
943 /// Provides a `String` by cloning.
944 ///
945 /// ```rust
f2b60f7d
FG
946 /// #![feature(provide_any)]
947 ///
923072b8
FG
948 /// use std::any::{Provider, Demand};
949 /// # struct SomeConcreteType { field: String }
950 ///
951 /// impl Provider for SomeConcreteType {
952 /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
f2b60f7d 953 /// demand.provide_value_with::<String>(|| self.field.clone());
923072b8
FG
954 /// }
955 /// }
956 /// ```
957 #[unstable(feature = "provide_any", issue = "96024")]
f2b60f7d 958 pub fn provide_value_with<T>(&mut self, fulfil: impl FnOnce() -> T) -> &mut Self
923072b8
FG
959 where
960 T: 'static,
923072b8 961 {
064997fb 962 self.provide_with::<tags::Value<T>>(fulfil)
923072b8
FG
963 }
964
f2b60f7d 965 /// Provide a reference. The referee type must be bounded by `'static`,
923072b8
FG
966 /// but may be unsized.
967 ///
968 /// # Examples
969 ///
970 /// Provides a reference to a field as a `&str`.
971 ///
972 /// ```rust
f2b60f7d
FG
973 /// #![feature(provide_any)]
974 ///
923072b8
FG
975 /// use std::any::{Provider, Demand};
976 /// # struct SomeConcreteType { field: String }
977 ///
978 /// impl Provider for SomeConcreteType {
979 /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
980 /// demand.provide_ref::<str>(&self.field);
981 /// }
982 /// }
983 /// ```
984 #[unstable(feature = "provide_any", issue = "96024")]
985 pub fn provide_ref<T: ?Sized + 'static>(&mut self, value: &'a T) -> &mut Self {
986 self.provide::<tags::Ref<tags::MaybeSizedValue<T>>>(value)
987 }
988
f2b60f7d
FG
989 /// Provide a reference computed using a closure. The referee type
990 /// must be bounded by `'static`, but may be unsized.
991 ///
992 /// # Examples
993 ///
994 /// Provides a reference to a field as a `&str`.
995 ///
996 /// ```rust
997 /// #![feature(provide_any)]
998 ///
999 /// use std::any::{Provider, Demand};
1000 /// # struct SomeConcreteType { business: String, party: String }
1001 /// # fn today_is_a_weekday() -> bool { true }
1002 ///
1003 /// impl Provider for SomeConcreteType {
1004 /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
1005 /// demand.provide_ref_with::<str>(|| {
1006 /// if today_is_a_weekday() {
1007 /// &self.business
1008 /// } else {
1009 /// &self.party
1010 /// }
1011 /// });
1012 /// }
1013 /// }
1014 /// ```
1015 #[unstable(feature = "provide_any", issue = "96024")]
1016 pub fn provide_ref_with<T: ?Sized + 'static>(
1017 &mut self,
1018 fulfil: impl FnOnce() -> &'a T,
1019 ) -> &mut Self {
1020 self.provide_with::<tags::Ref<tags::MaybeSizedValue<T>>>(fulfil)
1021 }
1022
923072b8
FG
1023 /// Provide a value with the given `Type` tag.
1024 fn provide<I>(&mut self, value: I::Reified) -> &mut Self
1025 where
1026 I: tags::Type<'a>,
1027 {
1028 if let Some(res @ TaggedOption(None)) = self.0.downcast_mut::<I>() {
1029 res.0 = Some(value);
1030 }
1031 self
1032 }
1033
1034 /// Provide a value with the given `Type` tag, using a closure to prevent unnecessary work.
064997fb 1035 fn provide_with<I>(&mut self, fulfil: impl FnOnce() -> I::Reified) -> &mut Self
923072b8
FG
1036 where
1037 I: tags::Type<'a>,
923072b8
FG
1038 {
1039 if let Some(res @ TaggedOption(None)) = self.0.downcast_mut::<I>() {
1040 res.0 = Some(fulfil());
1041 }
1042 self
1043 }
f2b60f7d
FG
1044
1045 /// Check if the `Demand` would be satisfied if provided with a
1046 /// value of the specified type. If the type does not match or has
1047 /// already been provided, returns false.
1048 ///
1049 /// # Examples
1050 ///
1051 /// Check if an `u8` still needs to be provided and then provides
1052 /// it.
1053 ///
1054 /// ```rust
1055 /// #![feature(provide_any)]
1056 ///
1057 /// use std::any::{Provider, Demand};
1058 ///
1059 /// struct Parent(Option<u8>);
1060 ///
1061 /// impl Provider for Parent {
1062 /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
1063 /// if let Some(v) = self.0 {
1064 /// demand.provide_value::<u8>(v);
1065 /// }
1066 /// }
1067 /// }
1068 ///
1069 /// struct Child {
1070 /// parent: Parent,
1071 /// }
1072 ///
1073 /// impl Child {
1074 /// // Pretend that this takes a lot of resources to evaluate.
1075 /// fn an_expensive_computation(&self) -> Option<u8> {
1076 /// Some(99)
1077 /// }
1078 /// }
1079 ///
1080 /// impl Provider for Child {
1081 /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
1082 /// // In general, we don't know if this call will provide
1083 /// // an `u8` value or not...
1084 /// self.parent.provide(demand);
1085 ///
1086 /// // ...so we check to see if the `u8` is needed before
1087 /// // we run our expensive computation.
1088 /// if demand.would_be_satisfied_by_value_of::<u8>() {
1089 /// if let Some(v) = self.an_expensive_computation() {
1090 /// demand.provide_value::<u8>(v);
1091 /// }
1092 /// }
1093 ///
1094 /// // The demand will be satisfied now, regardless of if
1095 /// // the parent provided the value or we did.
1096 /// assert!(!demand.would_be_satisfied_by_value_of::<u8>());
1097 /// }
1098 /// }
1099 ///
1100 /// let parent = Parent(Some(42));
1101 /// let child = Child { parent };
1102 /// assert_eq!(Some(42), std::any::request_value::<u8>(&child));
1103 ///
1104 /// let parent = Parent(None);
1105 /// let child = Child { parent };
1106 /// assert_eq!(Some(99), std::any::request_value::<u8>(&child));
1107 /// ```
1108 #[unstable(feature = "provide_any", issue = "96024")]
1109 pub fn would_be_satisfied_by_value_of<T>(&self) -> bool
1110 where
1111 T: 'static,
1112 {
1113 self.would_be_satisfied_by::<tags::Value<T>>()
1114 }
1115
1116 /// Check if the `Demand` would be satisfied if provided with a
1117 /// reference to a value of the specified type. If the type does
1118 /// not match or has already been provided, returns false.
1119 ///
1120 /// # Examples
1121 ///
1122 /// Check if a `&str` still needs to be provided and then provides
1123 /// it.
1124 ///
1125 /// ```rust
1126 /// #![feature(provide_any)]
1127 ///
1128 /// use std::any::{Provider, Demand};
1129 ///
1130 /// struct Parent(Option<String>);
1131 ///
1132 /// impl Provider for Parent {
1133 /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
1134 /// if let Some(v) = &self.0 {
1135 /// demand.provide_ref::<str>(v);
1136 /// }
1137 /// }
1138 /// }
1139 ///
1140 /// struct Child {
1141 /// parent: Parent,
1142 /// name: String,
1143 /// }
1144 ///
1145 /// impl Child {
1146 /// // Pretend that this takes a lot of resources to evaluate.
1147 /// fn an_expensive_computation(&self) -> Option<&str> {
1148 /// Some(&self.name)
1149 /// }
1150 /// }
1151 ///
1152 /// impl Provider for Child {
1153 /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
1154 /// // In general, we don't know if this call will provide
1155 /// // a `str` reference or not...
1156 /// self.parent.provide(demand);
1157 ///
1158 /// // ...so we check to see if the `&str` is needed before
1159 /// // we run our expensive computation.
1160 /// if demand.would_be_satisfied_by_ref_of::<str>() {
1161 /// if let Some(v) = self.an_expensive_computation() {
1162 /// demand.provide_ref::<str>(v);
1163 /// }
1164 /// }
1165 ///
1166 /// // The demand will be satisfied now, regardless of if
1167 /// // the parent provided the reference or we did.
1168 /// assert!(!demand.would_be_satisfied_by_ref_of::<str>());
1169 /// }
1170 /// }
1171 ///
1172 /// let parent = Parent(Some("parent".into()));
1173 /// let child = Child { parent, name: "child".into() };
1174 /// assert_eq!(Some("parent"), std::any::request_ref::<str>(&child));
1175 ///
1176 /// let parent = Parent(None);
1177 /// let child = Child { parent, name: "child".into() };
1178 /// assert_eq!(Some("child"), std::any::request_ref::<str>(&child));
1179 /// ```
1180 #[unstable(feature = "provide_any", issue = "96024")]
1181 pub fn would_be_satisfied_by_ref_of<T>(&self) -> bool
1182 where
1183 T: ?Sized + 'static,
1184 {
1185 self.would_be_satisfied_by::<tags::Ref<tags::MaybeSizedValue<T>>>()
1186 }
1187
1188 fn would_be_satisfied_by<I>(&self) -> bool
1189 where
1190 I: tags::Type<'a>,
1191 {
1192 matches!(self.0.downcast::<I>(), Some(TaggedOption(None)))
1193 }
923072b8
FG
1194}
1195
1196#[unstable(feature = "provide_any", issue = "96024")]
1197impl<'a> fmt::Debug for Demand<'a> {
1198 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1199 f.debug_struct("Demand").finish_non_exhaustive()
1200 }
1201}
1202
1203///////////////////////////////////////////////////////////////////////////////
1204// Type tags
1205///////////////////////////////////////////////////////////////////////////////
1206
1207mod tags {
1208 //! Type tags are used to identify a type using a separate value. This module includes type tags
1209 //! for some very common types.
1210 //!
1211 //! Currently type tags are not exposed to the user. But in the future, if you want to use the
1212 //! Provider API with more complex types (typically those including lifetime parameters), you
1213 //! will need to write your own tags.
1214
1215 use crate::marker::PhantomData;
1216
1217 /// This trait is implemented by specific tag types in order to allow
1218 /// describing a type which can be requested for a given lifetime `'a`.
1219 ///
1220 /// A few example implementations for type-driven tags can be found in this
1221 /// module, although crates may also implement their own tags for more
1222 /// complex types with internal lifetimes.
1223 pub trait Type<'a>: Sized + 'static {
1224 /// The type of values which may be tagged by this tag for the given
1225 /// lifetime.
1226 type Reified: 'a;
1227 }
1228
1229 /// Similar to the [`Type`] trait, but represents a type which may be unsized (i.e., has a
1230 /// `?Sized` bound). E.g., `str`.
1231 pub trait MaybeSizedType<'a>: Sized + 'static {
1232 type Reified: 'a + ?Sized;
1233 }
1234
1235 impl<'a, T: Type<'a>> MaybeSizedType<'a> for T {
1236 type Reified = T::Reified;
1237 }
1238
1239 /// Type-based tag for types bounded by `'static`, i.e., with no borrowed elements.
1240 #[derive(Debug)]
1241 pub struct Value<T: 'static>(PhantomData<T>);
1242
1243 impl<'a, T: 'static> Type<'a> for Value<T> {
1244 type Reified = T;
1245 }
1246
1247 /// Type-based tag similar to [`Value`] but which may be unsized (i.e., has a `?Sized` bound).
1248 #[derive(Debug)]
1249 pub struct MaybeSizedValue<T: ?Sized + 'static>(PhantomData<T>);
1250
1251 impl<'a, T: ?Sized + 'static> MaybeSizedType<'a> for MaybeSizedValue<T> {
1252 type Reified = T;
1253 }
1254
1255 /// Type-based tag for reference types (`&'a T`, where T is represented by
1256 /// `<I as MaybeSizedType<'a>>::Reified`.
1257 #[derive(Debug)]
1258 pub struct Ref<I>(PhantomData<I>);
1259
1260 impl<'a, I: MaybeSizedType<'a>> Type<'a> for Ref<I> {
1261 type Reified = &'a I::Reified;
1262 }
1263}
1264
1265/// An `Option` with a type tag `I`.
1266///
1267/// Since this struct implements `Erased`, the type can be erased to make a dynamically typed
1268/// option. The type can be checked dynamically using `Erased::tag_id` and since this is statically
1269/// checked for the concrete type, there is some degree of type safety.
1270#[repr(transparent)]
1271struct TaggedOption<'a, I: tags::Type<'a>>(Option<I::Reified>);
1272
1273impl<'a, I: tags::Type<'a>> TaggedOption<'a, I> {
1274 fn as_demand(&mut self) -> &mut Demand<'a> {
1275 Demand::new(self as &mut (dyn Erased<'a> + 'a))
1276 }
1277}
1278
1279/// Represents a type-erased but identifiable object.
1280///
1281/// This trait is exclusively implemented by the `TaggedOption` type.
1282unsafe trait Erased<'a>: 'a {
1283 /// The `TypeId` of the erased type.
1284 fn tag_id(&self) -> TypeId;
1285}
1286
1287unsafe impl<'a, I: tags::Type<'a>> Erased<'a> for TaggedOption<'a, I> {
1288 fn tag_id(&self) -> TypeId {
1289 TypeId::of::<I>()
1290 }
1291}
1292
1293#[unstable(feature = "provide_any", issue = "96024")]
1294impl<'a> dyn Erased<'a> + 'a {
1295 /// Returns some reference to the dynamic value if it is tagged with `I`,
1296 /// or `None` otherwise.
1297 #[inline]
f2b60f7d
FG
1298 fn downcast<I>(&self) -> Option<&TaggedOption<'a, I>>
1299 where
1300 I: tags::Type<'a>,
1301 {
1302 if self.tag_id() == TypeId::of::<I>() {
1303 // SAFETY: Just checked whether we're pointing to an I.
1304 Some(unsafe { &*(self as *const Self).cast::<TaggedOption<'a, I>>() })
1305 } else {
1306 None
1307 }
1308 }
1309
1310 /// Returns some mutable reference to the dynamic value if it is tagged with `I`,
1311 /// or `None` otherwise.
1312 #[inline]
923072b8
FG
1313 fn downcast_mut<I>(&mut self) -> Option<&mut TaggedOption<'a, I>>
1314 where
1315 I: tags::Type<'a>,
1316 {
1317 if self.tag_id() == TypeId::of::<I>() {
1318 // SAFETY: Just checked whether we're pointing to an I.
1319 Some(unsafe { &mut *(self as *mut Self).cast::<TaggedOption<'a, I>>() })
1320 } else {
1321 None
1322 }
1323 }
1324}