You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

yoke

Package Overview
Dependencies
Maintainers
1
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

yoke - cargo Package Compare versions

Comparing version
0.7.4
to
0.7.5
+1
-1
.cargo_vcs_info.json
{
"git": {
"sha1": "55cd12ebb25c6261492e1e3dfa2e6453c54dde31"
"sha1": "6bd4893cc44c2ca2718de47a119a31cc40045fe5"
},
"path_in_vcs": "utils/yoke"
}

@@ -14,6 +14,7 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO

edition = "2021"
rust-version = "1.67"
rust-version = "1.71.1"
name = "yoke"
version = "0.7.4"
version = "0.7.5"
authors = ["Manish Goregaokar <manishsmail@gmail.com>"]
build = false
include = [

@@ -29,2 +30,6 @@ "data/**/*",

]
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "Abstraction allowing borrowed data to be carried along with the backing data it borrows from"

@@ -57,2 +62,14 @@ readme = "README.md"

[lib]
name = "yoke"
path = "src/lib.rs"
[[test]]
name = "bincode"
path = "tests/bincode.rs"
[[test]]
name = "miri"
path = "tests/miri.rs"
[dependencies.serde]

@@ -68,3 +85,3 @@ version = "1.0.110"

[dependencies.yoke-derive]
version = "0.7.4"
version = "0.7.5"
optional = true

@@ -71,0 +88,0 @@ default-features = false

@@ -33,5 +33,13 @@ // This file is part of ICU4X. For terms of use, please see the file

// Safety note: this method MUST return the same value for the same T, even if i.e. the method gets
// instantiated in different crates. This can be untrue in surprising ways! For example, just
// returning a const-ref-to-const would not guarantee that.
// The current implementation always returns the same address for any T, see
// [the reference](https://doc.rust-lang.org/reference/items/static-items.html#statics--generics):
// there is exactly one `SENTINEL` item for any T.
#[inline]
fn sentinel_for<T>() -> NonNull<T> {
static SENTINEL: &u8 = &0x1a; // SUB
// Safety: SENTINEL is indeed not a null pointer, even after the casts.
unsafe { NonNull::new_unchecked(SENTINEL as *const u8 as *mut T) }

@@ -60,4 +68,6 @@ }

/// 2. `drop_raw` returns ownership back to the impl, if there is ownership to transfer
/// 3. `into_raw` must not return the sentinel pointer
///
/// Note: if `into_raw` returns the sentinel pointer, memory leaks may occur, but this will not
/// lead to undefined behaviour.
///
/// Note: the pointer `NonNull<Self::Raw>` may or may not be aligned and it should never

@@ -114,3 +124,2 @@ /// be dereferenced. Rust allows unaligned pointers; see [`std::ptr::read_unaligned`].

// 2. There is no ownership to transfer
// 3. External clients do not have the sentinel address so it won't be used in this reference.
unsafe impl<'a, T> CartablePointerLike for &'a T {

@@ -142,2 +151,3 @@ type Raw = T;

#[cfg(feature = "alloc")]
// Safety:

@@ -148,4 +158,2 @@ // 1. `Box::into_raw` says: "After calling this function, the caller is responsible for the

// resulting Box."
// 3. The pointer comes from the Box so it won't be the sentinel pointer.
#[cfg(feature = "alloc")]
unsafe impl<T> CartablePointerLike for Box<T> {

@@ -161,3 +169,6 @@ type Raw = T;

unsafe fn drop_raw(pointer: NonNull<T>) {
let _box = Box::from_raw(pointer.as_ptr());
// Safety: per the method's precondition, `pointer` is dereferenceable and was returned by
// `Self::into_raw`, i.e. by `Box::into_raw`. In this circumstances, calling
// `Box::from_raw` is safe.
let _box = unsafe { Box::from_raw(pointer.as_ptr()) };

@@ -173,2 +184,3 @@ // Boxes are always dropped

#[cfg(feature = "alloc")]
// Safety:

@@ -178,4 +190,2 @@ // 1. `Rc::into_raw` says: "Consumes the Rc, returning the wrapped pointer. To avoid a memory

// 2. See 1.
// 3. The pointer comes from the Rc so it won't be the sentinel pointer.
#[cfg(feature = "alloc")]
unsafe impl<T> CartablePointerLike for Rc<T> {

@@ -189,5 +199,9 @@ type Raw = T;

}
#[inline]
unsafe fn drop_raw(pointer: NonNull<T>) {
let _rc = Rc::from_raw(pointer.as_ptr());
// Safety: per the method's precondition, `pointer` is dereferenceable and was returned by
// `Self::into_raw`, i.e. by `Rc::into_raw`. In this circumstances, calling
// `Rc::from_raw` is safe.
let _rc = unsafe { Rc::from_raw(pointer.as_ptr()) };

@@ -202,6 +216,6 @@ // Rc is dropped if refcount is 1

#[cfg(feature = "alloc")]
// Safety:
// 1. The impl increases the refcount such that `Drop` will decrease it.
// 2. The impl increases refcount without changing the address of data.
#[cfg(feature = "alloc")]
unsafe impl<T> CloneableCartablePointerLike for Rc<T> {

@@ -214,3 +228,5 @@ #[inline]

// Further, this impl is not defined for anything but the global allocator.
Rc::increment_strong_count(pointer.as_ptr());
unsafe {
Rc::increment_strong_count(pointer.as_ptr());
}
}

@@ -222,2 +238,3 @@ }

#[cfg(feature = "alloc")]
// Safety:

@@ -227,4 +244,2 @@ // 1. `Rc::into_raw` says: "Consumes the Arc, returning the wrapped pointer. To avoid a memory

// 2. See 1.
// 3. The pointer comes from the Arc so it won't be the sentinel pointer.
#[cfg(feature = "alloc")]
unsafe impl<T> CartablePointerLike for Arc<T> {

@@ -240,3 +255,6 @@ type Raw = T;

unsafe fn drop_raw(pointer: NonNull<T>) {
let _arc = Arc::from_raw(pointer.as_ptr());
// Safety: per the method's precondition, `pointer` is dereferenceable and was returned by
// `Self::into_raw`, i.e. by `Rc::into_raw`. In this circumstances, calling
// `Rc::from_raw` is safe.
let _arc = unsafe { Arc::from_raw(pointer.as_ptr()) };

@@ -251,6 +269,6 @@ // Arc is dropped if refcount is 1

#[cfg(feature = "alloc")]
// Safety:
// 1. The impl increases the refcount such that `Drop` will decrease it.
// 2. The impl increases refcount without changing the address of data.
#[cfg(feature = "alloc")]
unsafe impl<T> CloneableCartablePointerLike for Arc<T> {

@@ -263,3 +281,5 @@ #[inline]

// Further, this impl is not defined for anything but the global allocator.
Arc::increment_strong_count(pointer.as_ptr());
unsafe {
Arc::increment_strong_count(pointer.as_ptr());
}
}

@@ -305,4 +325,6 @@ }

pub(crate) fn from_cartable(cartable: C) -> Self {
let inner = cartable.into_raw();
debug_assert_ne!(inner, sentinel_for::<C::Raw>());
Self {
inner: cartable.into_raw(),
inner,
_cartable: PhantomData,

@@ -309,0 +331,0 @@ }

@@ -70,3 +70,3 @@ // This file is part of ICU4X. For terms of use, please see the file

// Safe because both sub-types implement the trait.
// Safety: Safe because both sub-types implement the trait.
unsafe impl<C0, C1, T> StableDeref for EitherCart<C0, C1>

@@ -81,3 +81,3 @@ where

// Safe because both sub-types implement the trait.
// Safety: Safe because both sub-types implement the trait.
unsafe impl<C0, C1> CloneableCart for EitherCart<C0, C1>

@@ -84,0 +84,0 @@ where

@@ -14,3 +14,4 @@ // This file is part of ICU4X. For terms of use, please see the file

///
/// See [#3696] for a testcase where `Yoke` fails this under miri's field-retagging mode.
/// See [#3696] for a testcase where `Yoke` fails under miri's field-retagging mode if not using
/// KindaSortaDangling.
///

@@ -63,4 +64,4 @@ /// This has `T: 'static` since we don't need anything

fn deref(&self) -> &T {
// Safety: Safe due to the safety invariant on `dangle`;
// we can always assume initialized
// Safety: Due to the safety invariant on `dangle`, it is guaranteed to be always
// initialized as deref is never called during drop.
unsafe { self.dangle.assume_init_ref() }

@@ -73,4 +74,4 @@ }

fn deref_mut(&mut self) -> &mut T {
// Safety: Safe due to the safety invariant on `dangle`;
// we can always assume initialized
// Safety: Due to the safety invariant on `dangle`, it is guaranteed to be always
// initialized as deref_mut is never called during drop.
unsafe { self.dangle.assume_init_mut() }

@@ -83,13 +84,13 @@ }

fn drop(&mut self) {
// Safety: We are reading and dropping a valid initialized T.
//
// As `drop_in_place()` is a `read()`-like duplication operation we must be careful that the original value isn't
// used afterwards. It won't be because this is drop and the only
// code that will run after this is `self`'s drop glue, and that drop glue is empty
// because MaybeUninit has no drop.
//
// We use `drop_in_place()` instead of `let _ = ... .assume_init_read()` to avoid creating a move
// of the inner `T` (without `KindaSortaDangling` protection!) type into a local -- we don't want to
// assert any of `T`'s memory-related validity properties here.
unsafe {
// Safety: We are reading and dropping a valid initialized T.
//
// As `drop_in_place()` is a `read()`-like duplication operation we must be careful that the original value isn't
// used afterwards. It won't be because this is drop and the only
// code that will run after this is `self`'s drop glue, and that drop glue is empty
// because MaybeUninit has no drop.
//
// We use `drop_in_place()` instead of `let _ = ... .assume_init_read()` to avoid creating a move
// of the inner `T` (without `KindaSortaDangling` protection!) type into a local -- we don't want to
// assert any of `T`'s memory-related validity properties here.
self.dangle.as_mut_ptr().drop_in_place();

@@ -96,0 +97,0 @@ }

@@ -10,3 +10,6 @@ // This file is part of ICU4X. For terms of use, please see the file

use crate::Yokeable;
use core::{mem, ptr};
use core::{
mem::{self, ManuallyDrop},
ptr,
};

@@ -37,3 +40,5 @@ macro_rules! copy_yoke_impl {

macro_rules! impl_copy_type {
($ty:ident) => {
($ty:ty) => {
// Safety: all the types that this macro is used to generate impls of Yokeable for do not
// borrow any memory.
unsafe impl<'a> Yokeable<'a> for $ty {

@@ -46,2 +51,3 @@ type Output = Self;

impl_copy_type!(());
impl_copy_type!(u8);

@@ -64,5 +70,8 @@ impl_copy_type!(u16);

// obvious to the compiler that the lifetime is covariant
//
// Safety: the caller of this macro must ensure that `Self` is indeed covariant in 'a.
macro_rules! unsafe_complex_yoke_impl {
() => {
fn transform(&'a self) -> &'a Self::Output {
// Safety: equivalent to casting the lifetime. Macro caller ensures covariance.
unsafe { mem::transmute(self) }

@@ -73,5 +82,6 @@ }

debug_assert!(mem::size_of::<Self::Output>() == mem::size_of::<Self>());
// Safety: equivalent to casting the lifetime. Macro caller ensures covariance.
unsafe {
let ptr: *const Self::Output = (&self as *const Self).cast();
mem::forget(self);
let _ = ManuallyDrop::new(self);
ptr::read(ptr)

@@ -84,4 +94,6 @@ }

let ptr: *const Self = (&from as *const Self::Output).cast();
mem::forget(from);
ptr::read(ptr)
let _ = ManuallyDrop::new(from);
// Safety: `ptr` is certainly valid, aligned and points to a properly initialized value, as
// it comes from a value that was moved into a ManuallyDrop.
unsafe { ptr::read(ptr) }
}

@@ -94,2 +106,4 @@

// Cast away the lifetime of Self
// Safety: this is equivalent to f(transmute(self)), and the documentation of the trait
// method explains why doing so is sound.
unsafe { f(mem::transmute::<&'a mut Self, &'a mut Self::Output>(self)) }

@@ -100,2 +114,4 @@ }

// Safety: since T implements Yokeable<'a>, Option<T<'b>> must be covariant on 'b or the Yokeable
// implementation on T would be unsound.
unsafe impl<'a, T: 'static + for<'b> Yokeable<'b>> Yokeable<'a> for Option<T> {

@@ -106,2 +122,4 @@ type Output = Option<<T as Yokeable<'a>>::Output>;

// Safety: since T1, T2 implement Yokeable<'a>, (T1<'b>, T2<'b>) must be covariant on 'b or the Yokeable
// implementation on T would be unsound.
unsafe impl<'a, T1: 'static + for<'b> Yokeable<'b>, T2: 'static + for<'b> Yokeable<'b>> Yokeable<'a>

@@ -114,5 +132,7 @@ for (T1, T2)

unsafe impl<'a, T: Yokeable<'a>, const N: usize> Yokeable<'a> for [T; N] {
// Safety: since T implements Yokeable<'a>, [T<'b>; N] must be covariant on 'b or the Yokeable
// implementation on T would be unsound.
unsafe impl<'a, T: 'static + for<'b> Yokeable<'b>, const N: usize> Yokeable<'a> for [T; N] {
type Output = [<T as Yokeable<'a>>::Output; N];
unsafe_complex_yoke_impl!();
}

@@ -108,3 +108,3 @@ // This file is part of ICU4X. For terms of use, please see the file

//! impl MiniDataMarker for SimpleStruct {
//! type Yokeable = SimpleStruct;
//! type DataStruct = SimpleStruct;
//! }

@@ -301,3 +301,3 @@ //!

pub fn into_ref(self) -> &'a YokeTraitHack<T> {
// YokeTraitHack is repr(transparent) so it's always safe
// Safety: YokeTraitHack is repr(transparent) so it's always safe
// to transmute YTH<&T> to &YTH<T>

@@ -304,0 +304,0 @@ unsafe { mem::transmute::<YokeTraitHack<&T>, &YokeTraitHack<T>>(self) }

@@ -84,6 +84,10 @@ // This file is part of ICU4X. For terms of use, please see the file

// Safety invariant: this type can be anything, but `yokeable` may only contain references to
// StableDeref parts of this cart, and those references must be valid for the lifetime of
// this cart (it must own or borrow them). It's ok for this cart to contain stack data as long as it
// is not referenced by `yokeable` during construction. `attach_to_cart`, the typical constructor
// of this type, upholds this invariant, but other constructors like `replace_cart` need to uphold it.
// StableDeref parts of this cart, and the targets of those references must be valid for the
// lifetime of this cart (it must own or borrow them). It's ok for this cart to contain stack
// data as long as it is not referenced by `yokeable` during construction. `attach_to_cart`,
// the typical constructor of this type, upholds this invariant, but other constructors like
// `replace_cart` need to uphold it.
// The implementation guarantees that there are no live `yokeable`s that reference data
// in a `cart` when the `cart` is dropped; this is guaranteed in the drop glue through field
// order.
cart: C,

@@ -203,3 +207,8 @@ }

Self {
yokeable: KindaSortaDangling::new(unsafe { Y::make(deserialized) }),
yokeable: KindaSortaDangling::new(
// Safety: the resulting `yokeable` is dropped before the `cart` because
// of the Yoke invariant. See the safety docs at the bottom of this file
// for the justification of why yokeable could only borrow from the Cart.
unsafe { Y::make(deserialized) },
),
cart,

@@ -217,6 +226,12 @@ }

F: for<'de> FnOnce(&'de <C as Deref>::Target) -> Result<<Y as Yokeable<'de>>::Output, E>,
<C as Deref>::Target: 'static,
{
let deserialized = f(cart.deref())?;
Ok(Self {
yokeable: KindaSortaDangling::new(unsafe { Y::make(deserialized) }),
yokeable: KindaSortaDangling::new(
// Safety: the resulting `yokeable` is dropped before the `cart` because
// of the Yoke invariant. See the safety docs at the bottom of this file
// for the justification of why yokeable could only borrow from the Cart.
unsafe { Y::make(deserialized) },
),
cart,

@@ -373,2 +388,5 @@ })

Yoke {
// Safety note: the safety invariant of this function guarantees that
// the data that the yokeable references has its ownership (if any)
// transferred to the new cart before self.cart is dropped.
yokeable: self.yokeable,

@@ -472,6 +490,5 @@ cart: f(self.cart),

pub fn wrap_cart_in_option(self) -> Yoke<Y, Option<C>> {
unsafe {
// safe because the cart is preserved, just wrapped
self.replace_cart(Some)
}
// Safety: the cart is preserved (since it is just wrapped into a Some),
// so any data it owns is too.
unsafe { self.replace_cart(Some) }
}

@@ -504,2 +521,4 @@ }

Self {
// Safety note: this `yokeable` certainly does not reference data owned by (), so we do
// not have to worry about when the `yokeable` is dropped.
yokeable: KindaSortaDangling::new(yokeable),

@@ -516,2 +535,4 @@ cart: (),

pub fn into_yokeable(self) -> Y {
// Safety note: since `yokeable` cannot reference data owned by `()`, this is certainly
// safe.
self.yokeable.into_inner()

@@ -550,2 +571,3 @@ }

Self {
// Safety note: this `yokeable` is known not to borrow from the cart.
yokeable: KindaSortaDangling::new(yokeable),

@@ -622,2 +644,4 @@ cart: None,

Some(cart) => Yoke {
// Safety note: CartableOptionPointer::from_cartable only wraps the `cart`,
// so the data referenced by the yokeable is still live.
yokeable: self.yokeable,

@@ -627,2 +651,3 @@ cart: CartableOptionPointer::from_cartable(cart),

None => Yoke {
// Safety note: this Yokeable cannot refer to any data since self.cart is None.
yokeable: self.yokeable,

@@ -668,7 +693,13 @@ cart: CartableOptionPointer::none(),

#[cfg(feature = "alloc")]
// Safety: Rc<T> implements CloneStableDeref.
unsafe impl<T: ?Sized> CloneableCart for Rc<T> {}
#[cfg(feature = "alloc")]
// Safety: Arc<T> implements CloneStableDeref.
unsafe impl<T: ?Sized> CloneableCart for Arc<T> {}
// Safety: Option<T> cannot deref to anything that T doesn't already deref to.
unsafe impl<T: CloneableCart> CloneableCart for Option<T> {}
// Safety: &'a T is indeed StableDeref, and cloning it refers to the same data.
// &'a T does not own in the first place, so ownership is preserved.
unsafe impl<'a, T: ?Sized> CloneableCart for &'a T {}
// Safety: () cannot deref to anything.
unsafe impl CloneableCart for () {}

@@ -694,3 +725,7 @@

Yoke {
yokeable: KindaSortaDangling::new(unsafe { Y::make(this_hack.clone().0) }),
yokeable: KindaSortaDangling::new(
// Safety: C being a CloneableCart guarantees that the data referenced by the
// `yokeable` is kept alive by the clone of the cart.
unsafe { Y::make(this_hack.clone().0) },
),
cart: self.cart.clone(),

@@ -799,3 +834,3 @@ }

//
// Safety docs can be found below on `__project_safety_docs()`
// Safety docs can be found at the end of the file.
pub fn map_project<P, F>(self, f: F) -> Yoke<P, C>

@@ -811,3 +846,8 @@ where

Yoke {
yokeable: KindaSortaDangling::new(unsafe { P::make(p) }),
yokeable: KindaSortaDangling::new(
// Safety: the resulting `yokeable` is dropped before the `cart` because
// of the Yoke invariant. See the safety docs below for the justification of why
// yokeable could only borrow from the Cart.
unsafe { P::make(p) },
),
cart: self.cart,

@@ -833,3 +873,8 @@ }

Yoke {
yokeable: KindaSortaDangling::new(unsafe { P::make(p) }),
yokeable: KindaSortaDangling::new(
// Safety: the resulting `yokeable` is dropped before the `cart` because
// of the Yoke invariant. See the safety docs below for the justification of why
// yokeable could only borrow from the Cart.
unsafe { P::make(p) },
),
cart: self.cart.clone(),

@@ -910,3 +955,8 @@ }

Ok(Yoke {
yokeable: KindaSortaDangling::new(unsafe { P::make(p) }),
yokeable: KindaSortaDangling::new(
// Safety: the resulting `yokeable` is dropped before the `cart` because
// of the Yoke invariant. See the safety docs below for the justification of why
// yokeable could only borrow from the Cart.
unsafe { P::make(p) },
),
cart: self.cart,

@@ -932,3 +982,8 @@ })

Ok(Yoke {
yokeable: KindaSortaDangling::new(unsafe { P::make(p) }),
yokeable: KindaSortaDangling::new(
// Safety: the resulting `yokeable` is dropped before the `cart` because
// of the Yoke invariant. See the safety docs below for the justification of why
// yokeable could only borrow from the Cart.
unsafe { P::make(p) },
),
cart: self.cart.clone(),

@@ -960,3 +1015,8 @@ })

Yoke {
yokeable: KindaSortaDangling::new(unsafe { P::make(p) }),
yokeable: KindaSortaDangling::new(
// Safety: the resulting `yokeable` is dropped before the `cart` because
// of the Yoke invariant. See the safety docs below for the justification of why
// yokeable could only borrow from the Cart.
unsafe { P::make(p) },
),
cart: self.cart,

@@ -986,3 +1046,8 @@ }

Yoke {
yokeable: KindaSortaDangling::new(unsafe { P::make(p) }),
yokeable: KindaSortaDangling::new(
// Safety: the resulting `yokeable` is dropped before the `cart` because
// of the Yoke invariant. See the safety docs below for the justification of why
// yokeable could only borrow from the Cart.
unsafe { P::make(p) },
),
cart: self.cart.clone(),

@@ -1016,3 +1081,8 @@ }

Ok(Yoke {
yokeable: KindaSortaDangling::new(unsafe { P::make(p) }),
yokeable: KindaSortaDangling::new(
// Safety: the resulting `yokeable` is dropped before the `cart` because
// of the Yoke invariant. See the safety docs below for the justification of why
// yokeable could only borrow from the Cart.
unsafe { P::make(p) },
),
cart: self.cart,

@@ -1043,3 +1113,8 @@ })

Ok(Yoke {
yokeable: KindaSortaDangling::new(unsafe { P::make(p) }),
yokeable: KindaSortaDangling::new(
// Safety: the resulting `yokeable` is dropped before the `cart` because
// of the Yoke invariant. See the safety docs below for the justification of why
// yokeable could only borrow from the Cart.
unsafe { P::make(p) },
),
cart: self.cart.clone(),

@@ -1088,7 +1163,4 @@ })

pub fn erase_rc_cart(self) -> Yoke<Y, ErasedRcCart> {
unsafe {
// safe because the cart is preserved, just
// type-erased
self.replace_cart(|c| c as ErasedRcCart)
}
// Safety: safe because the cart is preserved, as it is just type-erased
unsafe { self.replace_cart(|c| c as ErasedRcCart) }
}

@@ -1135,7 +1207,4 @@ }

pub fn erase_arc_cart(self) -> Yoke<Y, ErasedArcCart> {
unsafe {
// safe because the cart is preserved, just
// type-erased
self.replace_cart(|c| c as ErasedArcCart)
}
// Safety: safe because the cart is preserved, as it is just type-erased
unsafe { self.replace_cart(|c| c as ErasedArcCart) }
}

@@ -1182,7 +1251,4 @@ }

pub fn erase_box_cart(self) -> Yoke<Y, ErasedBoxCart> {
unsafe {
// safe because the cart is preserved, just
// type-erased
self.replace_cart(|c| c as ErasedBoxCart)
}
// Safety: safe because the cart is preserved, as it is just type-erased
unsafe { self.replace_cart(|c| c as ErasedBoxCart) }
}

@@ -1199,6 +1265,4 @@ }

pub fn wrap_cart_in_box(self) -> Yoke<Y, Box<C>> {
unsafe {
// safe because the cart is preserved, just wrapped
self.replace_cart(Box::new)
}
// Safety: safe because the cart is preserved, as it is just wrapped.
unsafe { self.replace_cart(Box::new) }
}

@@ -1212,6 +1276,4 @@ /// Helper function allowing one to wrap the cart type `C` in an `Rc<T>`.

pub fn wrap_cart_in_rc(self) -> Yoke<Y, Rc<C>> {
unsafe {
// safe because the cart is preserved, just wrapped
self.replace_cart(Rc::new)
}
// Safety: safe because the cart is preserved, as it is just wrapped
unsafe { self.replace_cart(Rc::new) }
}

@@ -1225,6 +1287,4 @@ /// Helper function allowing one to wrap the cart type `C` in an `Rc<T>`.

pub fn wrap_cart_in_arc(self) -> Yoke<Y, Arc<C>> {
unsafe {
// safe because the cart is preserved, just wrapped
self.replace_cart(Arc::new)
}
// Safety: safe because the cart is preserved, as it is just wrapped
unsafe { self.replace_cart(Arc::new) }
}

@@ -1242,6 +1302,4 @@ }

pub fn wrap_cart_in_either_a<B>(self) -> Yoke<Y, EitherCart<C, B>> {
unsafe {
// safe because the cart is preserved, just wrapped
self.replace_cart(EitherCart::A)
}
// Safety: safe because the cart is preserved, as it is just wrapped.
unsafe { self.replace_cart(EitherCart::A) }
}

@@ -1256,6 +1314,4 @@ /// Helper function allowing one to wrap the cart type `C` in an [`EitherCart`].

pub fn wrap_cart_in_either_b<A>(self) -> Yoke<Y, EitherCart<A, C>> {
unsafe {
// safe because the cart is preserved, just wrapped
self.replace_cart(EitherCart::B)
}
// Safety: safe because the cart is preserved, as it is just wrapped.
unsafe { self.replace_cart(EitherCart::B) }
}

@@ -1271,2 +1327,4 @@ }

///
/// Note that correctness arguments are similar if you replace `fn` with `FnOnce`.
///
/// What we want this function to do is take a Yokeable (`Y`) that is borrowing from the cart, and

@@ -1273,0 +1331,0 @@ /// produce another Yokeable (`P`) that also borrows from the same cart. There are a couple potential

@@ -7,6 +7,8 @@ // This file is part of ICU4X. For terms of use, please see the file

use alloc::borrow::{Cow, ToOwned};
use core::mem;
use core::{marker::PhantomData, mem};
/// The `Yokeable<'a>` trait is implemented on the `'static` version of any zero-copy type; for
/// example, `Cow<'static, T>` implements `Yokeable<'a>` (for all `'a`). One can use
/// example, `Cow<'static, T>` implements `Yokeable<'a>` (for all `'a`).
///
/// One can use
/// `Yokeable::Output` on this trait to obtain the "lifetime'd" value of the `Cow<'static, T>`,

@@ -40,2 +42,4 @@ /// e.g. `<Cow<'static, T> as Yokeable<'a>'>::Output` is `Cow<'a, T>`.

///
/// This trait is also safe to implement on types that do not borrow memory.
///
/// There are further constraints on implementation safety on individual methods.

@@ -234,2 +238,15 @@ ///

/// ```
///
/// More formally, a reference to an object that `f` assigns to a reference
/// in Self<'a> could be obtained from:
/// - a local variable: the compiler rejects the assignment because 'a certainly
/// outlives local variables in f.
/// - a field in its argument: because of the for<'b> bound, the call to `f`
/// must be valid for a particular 'b that is strictly shorter than 'a. Thus,
/// the compiler rejects the assignment.
/// - a reference field in Self<'a>: this does not extend the set of
/// non-static lifetimes reachable from Self<'a>, so this is fine.
/// - one of f's captures: since F: 'static, the resulting reference must refer
/// to 'static data.
/// - a static or thread_local variable: ditto.
fn transform_mut<F>(&'a mut self, f: F)

@@ -242,2 +259,3 @@ where

#[cfg(feature = "alloc")]
// Safety: Cow<'a, _> is covariant in 'a.
unsafe impl<'a, T: 'static + ToOwned + ?Sized> Yokeable<'a> for Cow<'static, T>

@@ -265,4 +283,6 @@ where

let ptr: *const Self = (&from as *const Self::Output).cast();
mem::forget(from);
core::ptr::read(ptr)
let _ = core::mem::ManuallyDrop::new(from);
// Safety: `ptr` is certainly valid, aligned and points to a properly initialized value, as
// it comes from a value that was moved into a ManuallyDrop.
unsafe { core::ptr::read(ptr) }
}

@@ -275,2 +295,4 @@ #[inline]

// Cast away the lifetime of Self
// Safety: this is equivalent to f(transmute(self)), and the documentation of the trait
// method explains why doing so is sound.
unsafe { f(mem::transmute::<&'a mut Self, &'a mut Self::Output>(self)) }

@@ -280,2 +302,3 @@ }

// Safety: &'a T is covariant in 'a.
unsafe impl<'a, T: 'static + ?Sized> Yokeable<'a> for &'static T {

@@ -295,3 +318,5 @@ type Output = &'a T;

unsafe fn make(from: &'a T) -> Self {
mem::transmute(from)
// Safety: function safety invariant guarantees that the returned reference
// will never be used beyond its original lifetime.
unsafe { mem::transmute(from) }
}

@@ -304,2 +329,4 @@ #[inline]

// Cast away the lifetime of Self
// Safety: this is equivalent to f(transmute(self)), and the documentation of the trait
// method explains why doing so is sound.
unsafe { f(mem::transmute::<&'a mut Self, &'a mut Self::Output>(self)) }

@@ -310,2 +337,3 @@ }

#[cfg(feature = "alloc")]
// Safety: Vec<T: 'static> never borrows.
unsafe impl<'a, T: 'static> Yokeable<'a> for alloc::vec::Vec<T> {

@@ -315,3 +343,2 @@ type Output = alloc::vec::Vec<T>;

fn transform(&'a self) -> &'a alloc::vec::Vec<T> {
// Doesn't need unsafe: `'a` is covariant so this lifetime cast is always safe
self

@@ -321,3 +348,2 @@ }

fn transform_owned(self) -> alloc::vec::Vec<T> {
// Doesn't need unsafe: `'a` is covariant so this lifetime cast is always safe
self

@@ -334,5 +360,29 @@ }

{
// Doesn't need unsafe: `'a` is covariant so this lifetime cast is always safe
f(self)
}
}
// Safety: PhantomData is a ZST.
unsafe impl<'a, T: ?Sized + 'static> Yokeable<'a> for PhantomData<T> {
type Output = PhantomData<T>;
fn transform(&'a self) -> &'a Self::Output {
self
}
fn transform_owned(self) -> Self::Output {
self
}
unsafe fn make(from: Self::Output) -> Self {
from
}
fn transform_mut<F>(&'a mut self, f: F)
where
// be VERY CAREFUL changing this signature, it is very nuanced (see above)
F: 'static + for<'b> FnOnce(&'b mut Self::Output),
{
f(self)
}
}

Sorry, the diff of this file is not supported yet