From b3452cd1223b0e22fb76bb9f005e56c9309a79d8 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 23 Dec 2019 10:47:16 -0500 Subject: [PATCH] Make `Any` an unsafe trait --- src/libcore/any.rs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/libcore/any.rs b/src/libcore/any.rs index 4afea12a362c8..0f18d0f4e48c8 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -73,19 +73,16 @@ use crate::intrinsics; /// Most types implement `Any`. However, any type which contains a non-`'static` reference does not. /// See the [module-level documentation][mod] for more details. /// +/// This trait is notably `unsafe`. However, this does not affect any use of +/// this trait in downstream code, as it is always safe to use `Any`. The reason +/// that `Any` is unsafe is that the standard library relies on its +/// implementation returning appropriate `TypeId`s for safe downcasting. +/// However, no code outside the standard library can implement `Any` as it +/// would overlap with the standard libaries impl for all `'static` types. +/// /// [mod]: index.html -// This trait is not unsafe, though we rely on the specifics of it's sole impl's -// `type_id` function in unsafe code (e.g., `downcast`). Normally, that would be -// a problem, but because the only impl of `Any` is a blanket implementation, no -// other code can implement `Any`. -// -// We could plausibly make this trait unsafe -- it would not cause breakage, -// since we control all the implementations -- but we choose not to as that's -// both not really necessary and may confuse users about the distinction of -// unsafe traits and unsafe methods (i.e., `type_id` would still be safe to call, -// but we would likely want to indicate as such in documentation). #[stable(feature = "rust1", since = "1.0.0")] -pub trait Any: 'static { +pub unsafe trait Any: 'static { /// Gets the `TypeId` of `self`. /// /// # Examples @@ -105,7 +102,7 @@ pub trait Any: 'static { } #[stable(feature = "rust1", since = "1.0.0")] -impl Any for T { +unsafe impl Any for T { fn type_id(&self) -> TypeId { TypeId::of::() }