From cda81da6ea4c037ef036067d9cb98e80208ee525 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 22 Mar 2020 20:24:22 +0100 Subject: [PATCH] avoid unsafe code, use upcasting-trait instead (trick by oli) --- src/librustc/mir/interpret/error.rs | 41 +++++++++++------------------ 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index fd7f5361214f..d00eb7921a04 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -14,10 +14,7 @@ use rustc_hir as hir; use rustc_macros::HashStable; use rustc_session::CtfeBacktrace; use rustc_span::{def_id::DefId, Pos, Span}; -use std::{ - any::{Any, TypeId}, - fmt, mem, -}; +use std::{any::Any, fmt, mem}; #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, RustcEncodable, RustcDecodable)] pub enum ErrorHandled { @@ -513,32 +510,26 @@ impl fmt::Debug for ResourceExhaustionInfo { } } +/// A trait to work around not having trait object upcasting. +pub trait AsAny: Any { + fn as_any(&self) -> &dyn Any; +} + +impl AsAny for T { + #[inline(always)] + fn as_any(&self) -> &dyn Any { + self + } +} + /// A trait for machine-specific errors (or other "machine stop" conditions). -pub trait MachineStopType: Any + fmt::Debug + Send {} +pub trait MachineStopType: AsAny + fmt::Debug + Send {} impl MachineStopType for String {} -// Copy-pasted from `any.rs`; there does not seem to be a way to re-use that. impl dyn MachineStopType { - pub fn is(&self) -> bool { - // Get `TypeId` of the type this function is instantiated with. - let t = TypeId::of::(); - - // Get `TypeId` of the type in the trait object (`self`). - let concrete = self.type_id(); - - // Compare both `TypeId`s on equality. - t == concrete - } - + #[inline(always)] pub fn downcast_ref(&self) -> Option<&T> { - if self.is::() { - // SAFETY: just checked whether we are pointing to the correct type, and we can rely on - // that check for memory safety because `Any` is implemented for all types; no other - // impls can exist as they would conflict with our impl. - unsafe { Some(&*(self as *const dyn MachineStopType as *const T)) } - } else { - None - } + self.as_any().downcast_ref() } }