Skip to content

Commit

Permalink
Avoid rust-lang/rust#51443 by splitting CloneAny and CloneToAny t…
Browse files Browse the repository at this point in the history
…raits.
  • Loading branch information
azriel91 committed Apr 10, 2021
1 parent e270790 commit dc774d7
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 47 deletions.
107 changes: 72 additions & 35 deletions src/any.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
//! The different types of `Any` for use in a map.
//!
//! This stuff is all based on `std::any`, but goes a little further, with `CloneAny` being a
//! cloneable `Any` and with the `Send` and `Sync` bounds possible on both `Any` and `CloneAny`.
//! This is based on `std::any`, but goes a little further, with `CloneAny` being a
//! cloneable `Any`. `CloneAnySend`, `CloneAnySync`, and `CloneAnySendSync` further
//! retrict what can be placed in the map with the `Send` and `Sync` bounds.

use std::any::Any as StdAny;
use std::fmt;
Expand All @@ -10,50 +11,50 @@ use std::fmt;
pub trait CloneToAny {
/// Clone `self` into a new `Box<CloneAny>` object.
fn clone_to_any(&self) -> Box<dyn CloneAny>;

/// Clone `self` into a new `Box<CloneAny + Send>` object.
fn clone_to_any_send(&self) -> Box<dyn CloneAny + Send>
where
Self: Send;

/// Clone `self` into a new `Box<CloneAny + Sync>` object.
fn clone_to_any_sync(&self) -> Box<dyn CloneAny + Sync>
where
Self: Sync;

/// Clone `self` into a new `Box<CloneAny + Send + Sync>` object.
fn clone_to_any_send_sync(&self) -> Box<dyn CloneAny + Send + Sync>
where
Self: Send + Sync;
}

impl<T: Any + Clone> CloneToAny for T {
#[inline]
fn clone_to_any(&self) -> Box<dyn CloneAny> {
Box::new(self.clone())
}
}

#[doc(hidden)]
pub trait CloneToAnySend: Send {
/// Clone `self` into a new `Box<CloneAnySend + Send>` object.
fn clone_to_any_send(&self) -> Box<dyn CloneAnySend + Send>;
}

impl<T: Any + Send + Clone> CloneToAnySend for T {
#[inline]
fn clone_to_any_send(&self) -> Box<dyn CloneAny + Send>
where
Self: Send,
{
fn clone_to_any_send(&self) -> Box<dyn CloneAnySend + Send> {
Box::new(self.clone())
}
}

#[doc(hidden)]
pub trait CloneToAnySync: Sync {
/// Clone `self` into a new `Box<CloneAnySync + Sync>` object.
fn clone_to_any_sync(&self) -> Box<dyn CloneAnySync + Sync>;
}

impl<T: Any + Sync + Clone> CloneToAnySync for T {
#[inline]
fn clone_to_any_sync(&self) -> Box<dyn CloneAny + Sync>
where
Self: Sync,
{
fn clone_to_any_sync(&self) -> Box<dyn CloneAnySync + Sync> {
Box::new(self.clone())
}
}

#[doc(hidden)]
pub trait CloneToAnySendSync: Send + Sync {
/// Clone `self` into a new `Box<CloneAnySendSync + Send + Sync>` object.
fn clone_to_any_send_sync(&self) -> Box<dyn CloneAnySendSync + Send + Sync>;
}

impl<T: Any + Send + Sync + Clone> CloneToAnySendSync for T {
#[inline]
fn clone_to_any_send_sync(&self) -> Box<dyn CloneAny + Send + Sync>
where
Self: Send + Sync,
{
fn clone_to_any_send_sync(&self) -> Box<dyn CloneAnySendSync + Send + Sync> {
Box::new(self.clone())
}
}
Expand All @@ -65,6 +66,24 @@ macro_rules! define {
/// Every type with no non-`'static` references implements `Any`.
define!(CloneAny remainder);
};
(CloneAnySend) => {
/// A type to emulate dynamic typing.
///
/// Every type with no non-`'static` references implements `Any`.
define!(CloneAnySend remainder);
};
(CloneAnySync) => {
/// A type to emulate dynamic typing.
///
/// Every type with no non-`'static` references implements `Any`.
define!(CloneAnySync remainder);
};
(CloneAnySendSync) => {
/// A type to emulate dynamic typing.
///
/// Every type with no non-`'static` references implements `Any`.
define!(CloneAnySendSync remainder);
};
(Any) => {
/// A type to emulate dynamic typing with cloning.
///
Expand All @@ -89,6 +108,21 @@ macro_rules! define {
pub trait CloneAny: Any + CloneToAny { }
impl<T: StdAny + Clone> CloneAny for T { }
};
(CloneAnySend trait) => {
/// See also [`Any`](trait.Any.html) for a version without the `Clone + Send` requirements.
pub trait CloneAnySend: Any + CloneToAnySend { }
impl<T: StdAny + Send + Clone> CloneAnySend for T { }
};
(CloneAnySync trait) => {
/// See also [`Any`](trait.Any.html) for a version without the `Clone + Sync` requirements.
pub trait CloneAnySync: Any + CloneToAnySync { }
impl<T: StdAny + Sync + Clone> CloneAnySync for T { }
};
(CloneAnySendSync trait) => {
/// See also [`Any`](trait.Any.html) for a version without the `Clone + Send + Sync` requirements.
pub trait CloneAnySendSync: Any + CloneToAnySendSync { }
impl<T: StdAny + Send + Sync + Clone> CloneAnySendSync for T { }
};
(Any trait) => {
/// See also [`CloneAny`](trait.CloneAny.html) for a cloneable version of this trait.
pub trait Any: StdAny { }
Expand Down Expand Up @@ -162,12 +196,15 @@ implement!(Any, + Send);
implement!(Any, + Sync);
implement!(Any, + Send + Sync);
implement!(CloneAny,);
implement!(CloneAny, + Send);
implement!(CloneAny, + Sync);
implement!(CloneAny, + Send + Sync);
implement!(CloneAnySend, + Send);
implement!(CloneAnySync, + Sync);
implement!(CloneAnySendSync, + Send + Sync);

define!(CloneAny);
define!(CloneAnySend);
define!(CloneAnySync);
define!(CloneAnySendSync);
impl_clone!(dyn CloneAny, clone_to_any);
impl_clone!((dyn CloneAny + Send), clone_to_any_send);
impl_clone!((dyn CloneAny + Sync), clone_to_any_sync);
impl_clone!((dyn CloneAny + Send + Sync), clone_to_any_send_sync);
impl_clone!((dyn CloneAnySend + Send), clone_to_any_send);
impl_clone!((dyn CloneAnySync + Sync), clone_to_any_sync);
impl_clone!((dyn CloneAnySendSync + Send + Sync), clone_to_any_send_sync);
26 changes: 14 additions & 12 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! This crate provides the `AnyMap` type, a safe and convenient store for one value of each type.

#![warn(missing_docs, unused_results)]
#![allow(unused_doc_comments)]

//#![deny(warnings)]
use std::any::TypeId;
use std::marker::PhantomData;
Expand Down Expand Up @@ -344,7 +346,7 @@ impl<'a, A: ?Sized + UncheckedAnyExt, V: IntoBox<A>> VacantEntry<'a, A, V> {

#[cfg(test)]
mod tests {
use crate::any::{Any, CloneAny};
use crate::any::{Any, CloneAny, CloneAnySend, CloneAnySendSync, CloneAnySync};
use crate::{AnyMap, Entry, Map};

#[derive(Clone, Debug, PartialEq)]
Expand Down Expand Up @@ -473,17 +475,17 @@ mod tests {
assert_debug::<Map<dyn Any + Send>>();
assert_debug::<Map<dyn Any + Sync>>();
assert_debug::<Map<dyn Any + Send + Sync>>();
assert_send::<Map<dyn CloneAny + Send>>();
assert_send::<Map<dyn CloneAny + Send + Sync>>();
assert_sync::<Map<dyn CloneAny + Sync>>();
assert_sync::<Map<dyn CloneAny + Send + Sync>>();
assert_clone::<Map<dyn CloneAny + Send>>();
assert_clone::<Map<dyn CloneAny + Send + Sync>>();
assert_clone::<Map<dyn CloneAny + Sync>>();
assert_clone::<Map<dyn CloneAny + Send + Sync>>();
assert_send::<Map<dyn CloneAnySend + Send>>();
assert_send::<Map<dyn CloneAnySendSync + Send + Sync>>();
assert_sync::<Map<dyn CloneAnySync + Sync>>();
assert_sync::<Map<dyn CloneAnySendSync + Send + Sync>>();
assert_clone::<Map<dyn CloneAnySend + Send>>();
assert_clone::<Map<dyn CloneAnySendSync + Send + Sync>>();
assert_clone::<Map<dyn CloneAnySync + Sync>>();
assert_clone::<Map<dyn CloneAnySendSync + Send + Sync>>();
assert_debug::<Map<dyn CloneAny>>();
assert_debug::<Map<dyn CloneAny + Send>>();
assert_debug::<Map<dyn CloneAny + Sync>>();
assert_debug::<Map<dyn CloneAny + Send + Sync>>();
assert_debug::<Map<dyn CloneAnySend + Send>>();
assert_debug::<Map<dyn CloneAnySync + Sync>>();
assert_debug::<Map<dyn CloneAnySendSync + Send + Sync>>();
}
}

0 comments on commit dc774d7

Please sign in to comment.