From 9a4bd8c4081d382ee070ed5bb04b7ecad2f28e6a Mon Sep 17 00:00:00 2001 From: "leonardo.yvens" Date: Thu, 31 May 2018 16:37:19 -0300 Subject: [PATCH] Fix future object safety of `CloneAny` A proof of concept that `typemap` can be made to work with the stronger object-safety rules proposed in rust-lang/rust#50966 --- src/internals.rs | 50 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/src/internals.rs b/src/internals.rs index f88d5bf..e8ebf3b 100644 --- a/src/internals.rs +++ b/src/internals.rs @@ -30,27 +30,45 @@ pub trait CloneAny: Any { #[doc(hidden)] fn clone_any(&self) -> Box; #[doc(hidden)] - fn clone_any_send(&self) -> Box where Self: Send; + unsafe fn clone_any_send(&self) -> Box; #[doc(hidden)] - fn clone_any_sync(&self) -> Box where Self: Sync; + unsafe fn clone_any_sync(&self) -> Box; #[doc(hidden)] - fn clone_any_send_sync(&self) -> Box where Self: Send + Sync; + unsafe fn clone_any_send_sync(&self) -> Box; +} + +struct CloneAnySendSync(T); +unsafe impl Sync for CloneAnySendSync { } +unsafe impl Send for CloneAnySendSync { } + +impl CloneAny for CloneAnySendSync { + fn clone_any(&self) -> Box { + Box::new(self.0.clone()) + } + unsafe fn clone_any_send(&self) -> Box { + Box::new(CloneAnySendSync(self.0.clone())) + } + unsafe fn clone_any_sync(&self) -> Box { + Box::new(CloneAnySendSync(self.0.clone())) + } + unsafe fn clone_any_send_sync(&self) -> Box { + Box::new(CloneAnySendSync(self.0.clone())) + } } impl CloneAny for T { fn clone_any(&self) -> Box { Box::new(self.clone()) } - fn clone_any_send(&self) -> Box where Self: Send { - Box::new(self.clone()) + unsafe fn clone_any_send(&self) -> Box { + Box::new(CloneAnySendSync(self.clone())) } - fn clone_any_sync(&self) -> Box where Self: Sync { - Box::new(self.clone()) + unsafe fn clone_any_sync(&self) -> Box { + Box::new(CloneAnySendSync(self.clone())) } - fn clone_any_send_sync(&self) -> Box - where Self: Send + Sync { - Box::new(self.clone()) + unsafe fn clone_any_send_sync(&self) -> Box { + Box::new(CloneAnySendSync(self.clone())) } } @@ -59,15 +77,21 @@ impl Clone for Box { } impl Clone for Box { - fn clone(&self) -> Box { (**self).clone_any_send() } + fn clone(&self) -> Box { + unsafe { (**self).clone_any_send() } + } } impl Clone for Box { - fn clone(&self) -> Box { (**self).clone_any_sync() } + fn clone(&self) -> Box { + unsafe { (**self).clone_any_sync() } + } } impl Clone for Box { - fn clone(&self) -> Box { (**self).clone_any_send_sync() } + fn clone(&self) -> Box { + unsafe { (**self).clone_any_send_sync() } + } } unsafe impl UnsafeAnyExt for CloneAny {}