From 1c36bb2f690b7ef508baaf72462a165566f48130 Mon Sep 17 00:00:00 2001 From: sharnoff Date: Wed, 9 Dec 2020 22:43:59 +0000 Subject: [PATCH 1/2] add docs note about `Any::type_id` on smart pointers --- library/core/src/any.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/library/core/src/any.rs b/library/core/src/any.rs index d1951fbbf10..b140c9eb452 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` or `Arc` is that simply +//! calling `.type_id()` on the value will produce the `TypeId` of the +//! container, and not the underlying trait object. This can be avoided +//! converting the smart pointer into a `&dyn Any` instead, which will return +//! the object's type id. For example: +//! ``` +//! use std::any::{Any, TypeId}; +//! +//! let boxed: Box = 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(); +//! +//! // Both of these assertions pass +//! assert_eq!(actual_id, TypeId::of::()); +//! assert_eq!(boxed_id, TypeId::of::>()); +//! ``` +//! //! # Examples //! //! Consider a situation where we want to log out a value passed to a function. From 72a7f736106187fb09474130921dfa4bcc1ceac2 Mon Sep 17 00:00:00 2001 From: Max Sharnoff Date: Wed, 9 Dec 2020 23:13:24 +0000 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Camelid --- library/core/src/any.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/core/src/any.rs b/library/core/src/any.rs index b140c9eb452..eef8f2046d3 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -17,11 +17,12 @@ //! # 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` or `Arc` is that simply +//! especially with types like `Box` or `Arc`, is that simply //! calling `.type_id()` on the value will produce the `TypeId` of the -//! container, and not the underlying trait object. This can be avoided +//! *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 type id. For example: +//! the object's `TypeId`. For example: +//! //! ``` //! use std::any::{Any, TypeId}; //! @@ -32,7 +33,6 @@ //! // ... than this: //! let boxed_id = boxed.type_id(); //! -//! // Both of these assertions pass //! assert_eq!(actual_id, TypeId::of::()); //! assert_eq!(boxed_id, TypeId::of::>()); //! ```