diff options
Diffstat (limited to 'vendor/yoke/src/is_covariant.rs')
-rw-r--r-- | vendor/yoke/src/is_covariant.rs | 142 |
1 files changed, 0 insertions, 142 deletions
diff --git a/vendor/yoke/src/is_covariant.rs b/vendor/yoke/src/is_covariant.rs deleted file mode 100644 index 75d123c84..000000000 --- a/vendor/yoke/src/is_covariant.rs +++ /dev/null @@ -1,142 +0,0 @@ -// This file is part of ICU4X. For terms of use, please see the file -// called LICENSE at the top level of the ICU4X source tree -// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). - -#[cfg(feature = "alloc")] -use alloc::{ - borrow::{Cow, ToOwned}, - boxed::Box, - rc::Rc, - string::String, -}; - -/// A type implementing `IsCovariant<'a>` is covariant with respect to lifetime `'a`. -/// -/// Lifetime parameters that are safely cast in [`Yokeable`] are also valid for `IsCovariant`. -/// -/// `IsCovariant` exists primarily to serve in trait bounds. The primary use case is to safely -/// perform lifetime casting on trait objects (`dyn Trait`). This enables a type-erased [`Yoke`] -/// consisting of only trait objects. See the examples. -/// -/// `IsCovariant` is auto-implemented in [`#[derive(Yokeable)]`](macro@crate::Yokeable). -/// -/// # Safety -/// -/// This trait is safe to implement on types with a _covariant_ lifetime parameter. This will -/// occur when the lifetime parameter is used within references, but not in the arguments of -/// function pointers or in mutable positions (either in `&mut` or via interior mutability). -/// -/// If a struct has multiple lifetime parameters, only the one used in `IsCovariant<'a>` needs to -/// be covariant. -/// -/// # Examples -/// -/// Implementing on a simple struct with a single covariant lifetime: -/// -/// ``` -/// # use yoke::*; -/// struct MyStruct<'a>(&'a str); -/// -/// // This is safe because 'a is covariant -/// unsafe impl<'a> IsCovariant<'a> for MyStruct<'a> {} -/// ``` -/// -/// By constraining the trait `ExampleTrait<'a>` on `IsCovariant<'a>`, we can safely implement -/// [`Yokeable`] and [`ZeroFrom`] on its trait object: -/// -/// ``` -/// # use yoke::*; -/// # use zerofrom::*; -/// # use core::mem; -/// trait ExampleTrait<'a>: IsCovariant<'a> { -/// fn get_message(&self) -> &'a str; -/// } -/// -/// // This wrapper is required because of the blanket Yokeable impl on &'static T -/// pub struct ExampleTraitDynRef<'a>(pub &'a dyn ExampleTrait<'a>); -/// -/// // The following impl is safe because the trait object requires IsCovariant. -/// unsafe impl<'a> Yokeable<'a> for ExampleTraitDynRef<'static> { -/// type Output = ExampleTraitDynRef<'a>; -/// fn transform(&'a self) -> &'a Self::Output { -/// unsafe { mem::transmute(self) } -/// } -/// -/// fn transform_owned(self) -> Self::Output { -/// unsafe { mem::transmute(self) } -/// } -/// -/// unsafe fn make(from: Self::Output) -> Self { -/// unsafe { mem::transmute(from) } -/// } -/// -/// fn transform_mut<F>(&'a mut self, f: F) -/// where -/// F: 'static + FnOnce(&'a mut Self::Output), -/// { -/// unsafe { f(mem::transmute::<&mut Self, &mut Self::Output>(self)) } -/// } -/// } -/// -/// impl<'zf, 'a> ZeroFrom<'zf, dyn ExampleTrait<'a> + 'a> for ExampleTraitDynRef<'zf> { -/// fn zero_from(this: &'zf (dyn ExampleTrait<'a> + 'a)) -> ExampleTraitDynRef<'zf> { -/// // This is safe because the trait object requires IsCovariant. -/// ExampleTraitDynRef(unsafe { core::mem::transmute(this) }) -/// } -/// } -/// -/// // Implement ExampleTrait on the struct from the previous example -/// # struct MyStruct<'a>(&'a str); -/// # unsafe impl<'a> IsCovariant<'a> for MyStruct<'a> {} -/// impl<'a> ExampleTrait<'a> for MyStruct<'a> { -/// fn get_message(&self) -> &'a str { -/// self.0 -/// } -/// } -/// -/// // Example usage: a Yoke of a trait object -/// let s = "Hello World".to_string(); -/// let yoke: Yoke<ExampleTraitDynRef<'static>, Box<dyn ExampleTrait>> = -/// Yoke::attach_to_zero_copy_cart(Box::new(MyStruct(&s))); -/// -/// assert_eq!(yoke.get().0.get_message(), "Hello World"); -/// ``` -/// -/// [`Yoke`]: crate::Yoke -/// [`Yokeable`]: crate::Yokeable -/// [`ZeroFrom`]: crate::ZeroFrom -pub unsafe trait IsCovariant<'a>: 'a {} - -// IsCovariant is implemented on the standard library Copy types in macro_impls.rs - -// The following impls are safe because there is only one lifetime, 'a, and 'a is covariant - -unsafe impl<'a> IsCovariant<'a> for () {} - -unsafe impl<'a> IsCovariant<'a> for str {} -#[cfg(feature = "alloc")] -unsafe impl<'a> IsCovariant<'a> for String {} - -unsafe impl<'a, T: IsCovariant<'a>> IsCovariant<'a> for Option<T> {} - -unsafe impl<'a, T1: IsCovariant<'a>, T2: IsCovariant<'a>> IsCovariant<'a> for (T1, T2) {} - -unsafe impl<'a, T: IsCovariant<'a>> IsCovariant<'a> for [T] {} - -unsafe impl<'a, T: IsCovariant<'a>, const N: usize> IsCovariant<'a> for [T; N] {} - -#[cfg(feature = "alloc")] -unsafe impl<'a, T: IsCovariant<'a> + ?Sized> IsCovariant<'a> for Box<T> {} - -#[cfg(feature = "alloc")] -unsafe impl<'a, T: IsCovariant<'a> + ?Sized> IsCovariant<'a> for Rc<T> {} - -// This is safe because T has a covariant lifetime, and Cow's lifetime is also covariant -#[cfg(feature = "alloc")] -unsafe impl<'a, T: IsCovariant<'a> + ToOwned + ?Sized> IsCovariant<'a> for Cow<'a, T> where - <T as ToOwned>::Owned: Sized -{ -} - -// This is safe because T has a covariant lifetime, and the reference lifetime is also covariant -unsafe impl<'a, T: IsCovariant<'a> + ?Sized> IsCovariant<'a> for &'a T {} |