about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-01-02 04:12:48 +0000
committerbors <bors@rust-lang.org>2021-01-02 04:12:48 +0000
commitf6b6d5cf6486926a1c8dffe4ef793e214cb827c5 (patch)
treee046cd9eda96bcb84bc477dfc2e676ca0b04079d
parent0876f59b975a67ce79b0d83750f0d153f119b790 (diff)
parent72a7f736106187fb09474130921dfa4bcc1ceac2 (diff)
downloadrust-f6b6d5cf6486926a1c8dffe4ef793e214cb827c5.tar.gz
rust-f6b6d5cf6486926a1c8dffe4ef793e214cb827c5.zip
Auto merge of #79870 - sharnoff:smart-pointer-Any-type_id, r=shepmaster
Add docs note about `Any::type_id` on smart pointers

Fixes #79868.

There's an issue I've run into a couple times while using values of type `Box<dyn Any>` - essentially, calling `value.type_id()` doesn't dereference to the trait object, but uses the implementation of `Any` for `Box<dyn Any>`, giving us the `TypeId` of the container instead of the object inside it.

I couldn't find any notes about this in the documentation and - while it could be inferred from existing knowledge of Rust and the blanket implemenation of `Any` - I think it'd be nice to have a note about it in the documentation for the `any` module.

Anyways, here's a first draft of a section about it. I'm happy to revise wording :)
-rw-r--r--library/core/src/any.rs23
1 files changed, 23 insertions, 0 deletions
diff --git a/library/core/src/any.rs b/library/core/src/any.rs
index d1951fbbf10..eef8f2046d3 100644
--- a/library/core/src/any.rs
+++ b/library/core/src/any.rs
@@ -14,6 +14,29 @@
 //!
 //! [`Box`]: ../../std/boxed/struct.Box.html
 //!
+//! # Smart pointers and `dyn Any`
+//!
+//! One piece of behavior to keep in mind when using `Any` as a trait object,
+//! especially with types like `Box<dyn Any>` or `Arc<dyn Any>`, is that simply
+//! calling `.type_id()` on the value will produce the `TypeId` of the
+//! *container*, not the underlying trait object. This can be avoided by
+//! converting the smart pointer into a `&dyn Any` instead, which will return
+//! the object's `TypeId`. For example:
+//!
+//! ```
+//! use std::any::{Any, TypeId};
+//!
+//! let boxed: Box<dyn Any> = Box::new(3_i32);
+//!
+//! // You're more likely to want this:
+//! let actual_id = (&*boxed).type_id();
+//! // ... than this:
+//! let boxed_id = boxed.type_id();
+//!
+//! assert_eq!(actual_id, TypeId::of::<i32>());
+//! assert_eq!(boxed_id, TypeId::of::<Box<dyn Any>>());
+//! ```
+//!
 //! # Examples
 //!
 //! Consider a situation where we want to log out a value passed to a function.