diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-07 05:48:48 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-07 05:48:48 +0000 |
commit | ef24de24a82fe681581cc130f342363c47c0969a (patch) | |
tree | 0d494f7e1a38b95c92426f58fe6eaa877303a86c /vendor/yoke | |
parent | Releasing progress-linux version 1.74.1+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-ef24de24a82fe681581cc130f342363c47c0969a.tar.xz rustc-ef24de24a82fe681581cc130f342363c47c0969a.zip |
Merging upstream version 1.75.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/yoke')
-rw-r--r-- | vendor/yoke/.cargo-checksum.json | 2 | ||||
-rw-r--r-- | vendor/yoke/Cargo.toml | 19 | ||||
-rw-r--r-- | vendor/yoke/LICENSE | 79 | ||||
-rw-r--r-- | vendor/yoke/README.md | 4 | ||||
-rw-r--r-- | vendor/yoke/src/erased.rs | 8 | ||||
-rw-r--r-- | vendor/yoke/src/kinda_sorta_dangling.rs | 94 | ||||
-rw-r--r-- | vendor/yoke/src/lib.rs | 1 | ||||
-rw-r--r-- | vendor/yoke/src/yoke.rs | 99 | ||||
-rw-r--r-- | vendor/yoke/tests/bincode.rs | 83 | ||||
-rw-r--r-- | vendor/yoke/tests/miri.rs | 15 |
10 files changed, 320 insertions, 84 deletions
diff --git a/vendor/yoke/.cargo-checksum.json b/vendor/yoke/.cargo-checksum.json index f5a0ad2e7..0c84282d1 100644 --- a/vendor/yoke/.cargo-checksum.json +++ b/vendor/yoke/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"5a6f2a19935a914a211ba055aa3e55d3fd39a83376baced7aa1415631f746beb","LICENSE":"4ad7541d66a407234e2c84902124cef325c29f3e966353efdb800bedb8b8da21","README.md":"30321954bbc84770e2b50e8cc6da2a9e98f97698cbf1fe829747d4f3c6f6f791","src/either.rs":"cc98640a3b0aa349631c0bf5a54c18ec6e1ee638612b557e35e3a191e9178d42","src/erased.rs":"a97a1be3436314e34903a59330a8f61f96f5543c73d96853c09c32392dd09898","src/lib.rs":"3952340babcc97002faf3e12c29da9cc42c6c15870a930658a764236a80b2139","src/macro_impls.rs":"f81ac8af77ac3641bfee116d6295f5f756f92d4b3b6c7d43a228cd313174d355","src/trait_hack.rs":"34c6979cbacd85de650ba4a1f4b1cc344451e229172394f289432cdb7a4fa0c0","src/yoke.rs":"c3b2d01cf255b2f1192e2ebe31bc6c1df6710832fceb525be64ac0c26df1117a","src/yokeable.rs":"1b2e04f620ab7c06c557d23c44b7ebb67736ae239c44277f4fbefbacc011e549","src/zero_from.rs":"71d97f87e003db0eb0e97064509bdf9355622ccd655549f926b6a0d9119db3ee"},"package":"1848075a23a28f9773498ee9a0f2cf58fcbad4f8c0ccf84a210ab33c6ae495de"}
\ No newline at end of file +{"files":{"Cargo.toml":"8d60515d0ff0f2ff45e4e51972d6eb5884a280fd40993cdc8d3525d19dfde7f4","LICENSE":"853f87c96f3d249f200fec6db1114427bc8bdf4afddc93c576956d78152ce978","README.md":"7caeea392483abdb034071f43cd056c7a69940b77a0e65ad7f37f4657107d4a3","src/either.rs":"cc98640a3b0aa349631c0bf5a54c18ec6e1ee638612b557e35e3a191e9178d42","src/erased.rs":"ebd156e832b5e67c599c6938cfbe85cd11a6088818a6981f56911cffb49e0a5f","src/kinda_sorta_dangling.rs":"178a8185d03c45dbdccdc574aa95777d52d4a36bb224a0d7bc3f29b5de39576a","src/lib.rs":"a143f3e85539a73c909d950bcc20b101af353912b9898d4a5b091fae9fcdd874","src/macro_impls.rs":"f81ac8af77ac3641bfee116d6295f5f756f92d4b3b6c7d43a228cd313174d355","src/trait_hack.rs":"34c6979cbacd85de650ba4a1f4b1cc344451e229172394f289432cdb7a4fa0c0","src/yoke.rs":"99fb6866741ad0d4d704bb167db407cc0aeb5406b24c71fb4be43922023af0e5","src/yokeable.rs":"1b2e04f620ab7c06c557d23c44b7ebb67736ae239c44277f4fbefbacc011e549","src/zero_from.rs":"71d97f87e003db0eb0e97064509bdf9355622ccd655549f926b6a0d9119db3ee","tests/bincode.rs":"3cc3c73af5cd5e44deaf3eb172257d9e2eedbbc5bf4abc4e04648d21bb667f5b","tests/miri.rs":"fd119cfbf1abc39463e3be5145966962853d1f6771826c003449a06b3e8acbea"},"package":"61e38c508604d6bbbd292dadb3c02559aa7fff6b654a078a36217cad871636e4"}
\ No newline at end of file diff --git a/vendor/yoke/Cargo.toml b/vendor/yoke/Cargo.toml index f6e400a64..856db2a70 100644 --- a/vendor/yoke/Cargo.toml +++ b/vendor/yoke/Cargo.toml @@ -11,13 +11,16 @@ [package] edition = "2021" +rust-version = "1.66" name = "yoke" -version = "0.7.1" +version = "0.7.2" authors = ["Manish Goregaokar <manishsmail@gmail.com>"] include = [ + "data/**/*", "src/**/*", "examples/**/*", "benches/**/*", + "tests/**/*", "Cargo.toml", "LICENSE", "README.md", @@ -37,15 +40,18 @@ categories = [ "caching", "no-std", ] -license = "Unicode-DFS-2016" +license-file = "LICENSE" repository = "https://github.com/unicode-org/icu4x" -[package.metadata.workspaces] -independent = true +[package.metadata.cargo-all-features] +max_combination_size = 3 [package.metadata.docs.rs] all-features = true +[package.metadata.workspaces] +independent = true + [dependencies.serde] version = "1.0" optional = true @@ -56,8 +62,9 @@ version = "1.2.0" default-features = false [dependencies.yoke-derive] -version = "0.7.0" +version = "0.7.1" optional = true +default-features = false [dependencies.zerofrom] version = "0.1.1" @@ -84,3 +91,5 @@ derive = [ "dep:yoke-derive", "zerofrom/derive", ] +serde = ["dep:serde"] +zerofrom = ["dep:zerofrom"] diff --git a/vendor/yoke/LICENSE b/vendor/yoke/LICENSE index 9858d01ab..9845aa5f4 100644 --- a/vendor/yoke/LICENSE +++ b/vendor/yoke/LICENSE @@ -1,49 +1,42 @@ -UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE - -See Terms of Use <https://www.unicode.org/copyright.html> -for definitions of Unicode Inc.’s Data Files and Software. - -NOTICE TO USER: Carefully read the following legal agreement. -BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S -DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), -YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE -TERMS AND CONDITIONS OF THIS AGREEMENT. -IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE -THE DATA FILES OR SOFTWARE. +UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE -Copyright © 1991-2022 Unicode, Inc. All rights reserved. -Distributed under the Terms of Use in https://www.unicode.org/copyright.html. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Unicode data files and any associated documentation -(the "Data Files") or Unicode software and any associated documentation -(the "Software") to deal in the Data Files or Software -without restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, and/or sell copies of -the Data Files or Software, and to permit persons to whom the Data Files -or Software are furnished to do so, provided that either -(a) this copyright and permission notice appear with all copies -of the Data Files or Software, or -(b) this copyright and permission notice appear in associated -Documentation. - -THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT OF THIRD PARTY RIGHTS. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS -NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL -DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THE DATA FILES OR SOFTWARE. - -Except as contained in this notice, the name of a copyright holder -shall not be used in advertising or otherwise to promote the sale, -use or other dealings in these Data Files or Software without prior -written authorization of the copyright holder. +Copyright © 2020-2023 Unicode, Inc. + +NOTICE TO USER: Carefully read the following legal agreement. BY +DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR +SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT +DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of data files and any associated documentation (the "Data Files") or +software and any associated documentation (the "Software") to deal in the +Data Files or Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, and/or sell +copies of the Data Files or Software, and to permit persons to whom the +Data Files or Software are furnished to do so, provided that either (a) +this copyright and permission notice appear with all copies of the Data +Files or Software, or (b) this copyright and permission notice appear in +associated Documentation. + +THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF +THIRD PARTY RIGHTS. + +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE +BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, +OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA +FILES OR SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in these Data Files or Software without prior written +authorization of the copyright holder. — diff --git a/vendor/yoke/README.md b/vendor/yoke/README.md index f7577b8d0..23c1ac8c3 100644 --- a/vendor/yoke/README.md +++ b/vendor/yoke/README.md @@ -1,5 +1,7 @@ # yoke [![crates.io](https://img.shields.io/crates/v/yoke)](https://crates.io/crates/yoke) +<!-- cargo-rdme start --> + This crate provides [`Yoke<Y, C>`][Yoke], which allows one to "yoke" (attach) a zero-copy deserialized object (say, a [`Cow<'a, str>`](alloc::borrow::Cow)) to the source it was deserialized from, (say, an [`Rc<[u8]>`](alloc::rc::Rc)), known in this crate as a "cart", producing a type that looks like `Yoke<Cow<'static, str>, Rc<[u8]>>` @@ -22,6 +24,8 @@ when necessary. See the documentation of [`Yoke`] for more details. +<!-- cargo-rdme end --> + ## More Information For more information on development, authorship, contributing etc. please visit [`ICU4X home page`](https://github.com/unicode-org/icu4x). diff --git a/vendor/yoke/src/erased.rs b/vendor/yoke/src/erased.rs index bc4de9791..4395404a6 100644 --- a/vendor/yoke/src/erased.rs +++ b/vendor/yoke/src/erased.rs @@ -7,7 +7,7 @@ //! See the docs of [`Yoke::erase_rc_cart()`](crate::Yoke::erase_rc_cart) //! and [`Yoke::erase_box_cart()`](crate::Yoke::erase_box_cart) for more info. //! -//! Available with the `"alloc"` Cargo feature enabled. +//! ✨ *Enabled with the `alloc` Cargo feature.* use alloc::boxed::Box; use alloc::rc::Rc; @@ -25,17 +25,17 @@ impl<T: 'static> ErasedDestructor for T {} /// /// See the docs of [`Yoke::erase_arc_cart()`](crate::Yoke::erase_rc_cart) for more info. /// -/// Available with the `"alloc"` Cargo feature enabled. +/// ✨ *Enabled with the `alloc` Cargo feature.* pub type ErasedArcCart = Arc<dyn ErasedDestructor + Send + Sync>; /// A type-erased Cart that has `Rc` semantics /// /// See the docs of [`Yoke::erase_rc_cart()`](crate::Yoke::erase_rc_cart) for more info. /// -/// Available with the `"alloc"` Cargo feature enabled. +/// ✨ *Enabled with the `alloc` Cargo feature.* pub type ErasedRcCart = Rc<dyn ErasedDestructor>; /// A type-erased Cart that has `Box` semantics /// /// See the docs of [`Yoke::erase_box_cart()`](crate::Yoke::erase_box_cart) for more info. /// -/// Available with the `"alloc"` Cargo feature enabled. +/// ✨ *Enabled with the `alloc` Cargo feature.* pub type ErasedBoxCart = Box<dyn ErasedDestructor>; diff --git a/vendor/yoke/src/kinda_sorta_dangling.rs b/vendor/yoke/src/kinda_sorta_dangling.rs new file mode 100644 index 000000000..32e1f5709 --- /dev/null +++ b/vendor/yoke/src/kinda_sorta_dangling.rs @@ -0,0 +1,94 @@ +// 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 ). + +use core::mem::{ManuallyDrop, MaybeUninit}; +use core::ops::{Deref, DerefMut}; + +/// This type is intended to be similar to the type `MaybeDangling<T>` +/// proposed in [RFC 3336]. +/// +/// The effect of this is that in Rust's safety model, types inside here are not +/// expected to have any memory dependent validity properties (`dereferenceable`, `noalias`). +/// +/// See [#3696] for a testcase where `Yoke` fails this under miri's field-retagging mode. +/// +/// This has `T: 'static` since we don't need anything +/// else and we don't want to have to think (more) about variance over lifetimes or dropck. +/// +/// After [RFC 3336] lands we can use `MaybeDangling` instead. +/// +/// Note that a version of this type also exists publicly as the [`maybe_dangling`] +/// crate; which also exports a patched `ManuallyDrop` with similar semantics and +/// does not require `T: 'static`. Consider using this if you need something more general +/// and are okay with adding dependencies. +/// +/// [RFC 3336]: https://github.com/rust-lang/rfcs/pull/3336 +/// [#3696]: https://github.com/unicode-org/icu4x/issues/3696 +/// [`maybe_dangling`](https://docs.rs/maybe-dangling/0.1.0/maybe_dangling/struct.MaybeDangling.html) +#[repr(transparent)] +pub(crate) struct KindaSortaDangling<T: 'static> { + /// Safety invariant: This is always an initialized T, never uninit or other + /// invalid bit patterns. Its drop glue will execute during Drop::drop rather than + /// during the drop glue for KindaSortaDangling, which means that we have to be careful about + /// not touching the values as initialized during `drop` after that, but that's a short period of time. + dangle: MaybeUninit<T>, +} + +impl<T: 'static> KindaSortaDangling<T> { + #[inline] + pub(crate) const fn new(dangle: T) -> Self { + KindaSortaDangling { + dangle: MaybeUninit::new(dangle), + } + } + #[inline] + pub(crate) fn into_inner(self) -> T { + // Self has a destructor, we want to avoid having it be called + let manual = ManuallyDrop::new(self); + // Safety: + // We can call assume_init_read() due to the library invariant on this type, + // however since it is a read() we must be careful about data duplication. + // The only code using `self` after this is the drop glue, which we have disabled via + // the ManuallyDrop. + unsafe { manual.dangle.assume_init_read() } + } +} + +impl<T: 'static> Deref for KindaSortaDangling<T> { + type Target = T; + #[inline] + fn deref(&self) -> &T { + // Safety: Safe due to the safety invariant on `dangle`; + // we can always assume initialized + unsafe { self.dangle.assume_init_ref() } + } +} + +impl<T: 'static> DerefMut for KindaSortaDangling<T> { + #[inline] + fn deref_mut(&mut self) -> &mut T { + // Safety: Safe due to the safety invariant on `dangle`; + // we can always assume initialized + unsafe { self.dangle.assume_init_mut() } + } +} + +impl<T: 'static> Drop for KindaSortaDangling<T> { + #[inline] + fn drop(&mut self) { + 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(); + } + } +} diff --git a/vendor/yoke/src/lib.rs b/vendor/yoke/src/lib.rs index 289b47412..e5adca62f 100644 --- a/vendor/yoke/src/lib.rs +++ b/vendor/yoke/src/lib.rs @@ -48,6 +48,7 @@ extern crate alloc; pub mod either; #[cfg(feature = "alloc")] pub mod erased; +mod kinda_sorta_dangling; mod macro_impls; pub mod trait_hack; mod yoke; diff --git a/vendor/yoke/src/yoke.rs b/vendor/yoke/src/yoke.rs index ef76aa86a..22f14d3dc 100644 --- a/vendor/yoke/src/yoke.rs +++ b/vendor/yoke/src/yoke.rs @@ -5,6 +5,7 @@ use crate::either::EitherCart; #[cfg(feature = "alloc")] use crate::erased::{ErasedArcCart, ErasedBoxCart, ErasedRcCart}; +use crate::kinda_sorta_dangling::KindaSortaDangling; use crate::trait_hack::YokeTraitHack; use crate::Yokeable; use core::marker::PhantomData; @@ -74,14 +75,39 @@ use alloc::sync::Arc; /// assert_eq!(&**yoke.get(), "hello"); /// assert!(matches!(yoke.get(), &Cow::Borrowed(_))); /// ``` -#[derive(Debug)] pub struct Yoke<Y: for<'a> Yokeable<'a>, C> { // must be the first field for drop order // this will have a 'static lifetime parameter, that parameter is a lie - yokeable: Y, + yokeable: KindaSortaDangling<Y>, cart: C, } +// Manual `Debug` implementation, since the derived one would be unsound. +// See https://github.com/unicode-org/icu4x/issues/3685 +impl<Y: for<'a> Yokeable<'a>, C: core::fmt::Debug> core::fmt::Debug for Yoke<Y, C> +where + for<'a> <Y as Yokeable<'a>>::Output: core::fmt::Debug, +{ + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Yoke") + .field("yokeable", self.get()) + .field("cart", self.backing_cart()) + .finish() + } +} + +#[test] +fn test_debug() { + let local_data = "foo".to_owned(); + let y1 = Yoke::<alloc::borrow::Cow<'static, str>, Rc<String>>::attach_to_zero_copy_cart( + Rc::new(local_data), + ); + assert_eq!( + format!("{y1:?}"), + r#"Yoke { yokeable: "foo", cart: "foo" }"#, + ); +} + impl<Y: for<'a> Yokeable<'a>, C: StableDeref> Yoke<Y, C> where <C as Deref>::Target: 'static, @@ -129,7 +155,7 @@ where { let deserialized = f(cart.deref()); Self { - yokeable: unsafe { Y::make(deserialized) }, + yokeable: KindaSortaDangling::new(unsafe { Y::make(deserialized) }), cart, } } @@ -145,7 +171,7 @@ where { let deserialized = f(cart.deref())?; Ok(Self { - yokeable: unsafe { Y::make(deserialized) }, + yokeable: KindaSortaDangling::new(unsafe { Y::make(deserialized) }), cart, }) } @@ -418,7 +444,10 @@ impl<Y: for<'a> Yokeable<'a>> Yoke<Y, ()> { /// assert_eq!(yoke.get(), "hello"); /// ``` pub fn new_always_owned(yokeable: Y) -> Self { - Self { yokeable, cart: () } + Self { + yokeable: KindaSortaDangling::new(yokeable), + cart: (), + } } /// Obtain the yokeable out of a `Yoke<Y, ()>` @@ -427,7 +456,7 @@ impl<Y: for<'a> Yokeable<'a>> Yoke<Y, ()> { /// fine for `Yoke<Y, ()>` since there are no actual internal /// references pub fn into_yokeable(self) -> Y { - self.yokeable + self.yokeable.into_inner() } } @@ -456,9 +485,9 @@ impl<Y: for<'a> Yokeable<'a>, C: StableDeref> Yoke<Y, Option<C>> { /// /// assert_eq!(yoke.get(), "hello"); /// ``` - pub fn new_owned(yokeable: Y) -> Self { + pub const fn new_owned(yokeable: Y) -> Self { Self { - yokeable, + yokeable: KindaSortaDangling::new(yokeable), cart: None, } } @@ -470,7 +499,7 @@ impl<Y: for<'a> Yokeable<'a>, C: StableDeref> Yoke<Y, Option<C>> { pub fn try_into_yokeable(self) -> Result<Y, Self> { match self.cart { Some(_) => Err(self), - None => Ok(self.yokeable), + None => Ok(self.yokeable.into_inner()), } } } @@ -516,7 +545,7 @@ where // We have an &T not a T, and we can clone YokeTraitHack<T> let this_hack = YokeTraitHack(this).into_ref(); Yoke { - yokeable: unsafe { Y::make(this_hack.clone().0) }, + yokeable: KindaSortaDangling::new(unsafe { Y::make(this_hack.clone().0) }), cart: self.cart.clone(), } } @@ -630,9 +659,9 @@ impl<Y: for<'a> Yokeable<'a>, C> Yoke<Y, C> { PhantomData<&'a ()>, ) -> <P as Yokeable<'a>>::Output, { - let p = f(self.yokeable.transform_owned(), PhantomData); + let p = f(self.yokeable.into_inner().transform_owned(), PhantomData); Yoke { - yokeable: unsafe { P::make(p) }, + yokeable: KindaSortaDangling::new(unsafe { P::make(p) }), cart: self.cart, } } @@ -653,7 +682,7 @@ impl<Y: for<'a> Yokeable<'a>, C> Yoke<Y, C> { { let p = f(self.get(), PhantomData); Yoke { - yokeable: unsafe { P::make(p) }, + yokeable: KindaSortaDangling::new(unsafe { P::make(p) }), cart: self.cart.clone(), } } @@ -728,9 +757,9 @@ impl<Y: for<'a> Yokeable<'a>, C> Yoke<Y, C> { PhantomData<&'a ()>, ) -> Result<<P as Yokeable<'a>>::Output, E>, { - let p = f(self.yokeable.transform_owned(), PhantomData)?; + let p = f(self.yokeable.into_inner().transform_owned(), PhantomData)?; Ok(Yoke { - yokeable: unsafe { P::make(p) }, + yokeable: KindaSortaDangling::new(unsafe { P::make(p) }), cart: self.cart, }) } @@ -751,7 +780,7 @@ impl<Y: for<'a> Yokeable<'a>, C> Yoke<Y, C> { { let p = f(self.get(), PhantomData)?; Ok(Yoke { - yokeable: unsafe { P::make(p) }, + yokeable: KindaSortaDangling::new(unsafe { P::make(p) }), cart: self.cart.clone(), }) } @@ -772,9 +801,13 @@ impl<Y: for<'a> Yokeable<'a>, C> Yoke<Y, C> { where P: for<'a> Yokeable<'a>, { - let p = f(self.yokeable.transform_owned(), capture, PhantomData); + let p = f( + self.yokeable.into_inner().transform_owned(), + capture, + PhantomData, + ); Yoke { - yokeable: unsafe { P::make(p) }, + yokeable: KindaSortaDangling::new(unsafe { P::make(p) }), cart: self.cart, } } @@ -799,7 +832,7 @@ impl<Y: for<'a> Yokeable<'a>, C> Yoke<Y, C> { { let p = f(self.get(), capture, PhantomData); Yoke { - yokeable: unsafe { P::make(p) }, + yokeable: KindaSortaDangling::new(unsafe { P::make(p) }), cart: self.cart.clone(), } } @@ -822,9 +855,13 @@ impl<Y: for<'a> Yokeable<'a>, C> Yoke<Y, C> { where P: for<'a> Yokeable<'a>, { - let p = f(self.yokeable.transform_owned(), capture, PhantomData)?; + let p = f( + self.yokeable.into_inner().transform_owned(), + capture, + PhantomData, + )?; Ok(Yoke { - yokeable: unsafe { P::make(p) }, + yokeable: KindaSortaDangling::new(unsafe { P::make(p) }), cart: self.cart, }) } @@ -850,7 +887,7 @@ impl<Y: for<'a> Yokeable<'a>, C> Yoke<Y, C> { { let p = f(self.get(), capture, PhantomData)?; Ok(Yoke { - yokeable: unsafe { P::make(p) }, + yokeable: KindaSortaDangling::new(unsafe { P::make(p) }), cart: self.cart.clone(), }) } @@ -870,6 +907,8 @@ impl<Y: for<'a> Yokeable<'a>, C: 'static + Sized> Yoke<Y, Rc<C>> { /// In case the cart type `C` is not already an `Rc<T>`, you can use /// [`Yoke::wrap_cart_in_rc()`] to wrap it. /// + /// ✨ *Enabled with the `alloc` Cargo feature.* + /// /// # Example /// /// ```rust @@ -891,8 +930,6 @@ impl<Y: for<'a> Yokeable<'a>, C: 'static + Sized> Yoke<Y, Rc<C>> { /// /// // Now erased1 and erased2 have the same type! /// ``` - /// - /// Available with the `"alloc"` Cargo feature enabled. pub fn erase_rc_cart(self) -> Yoke<Y, ErasedRcCart> { unsafe { // safe because the cart is preserved, just @@ -916,6 +953,8 @@ impl<Y: for<'a> Yokeable<'a>, C: 'static + Sized + Send + Sync> Yoke<Y, Arc<C>> /// In case the cart type `C` is not already an `Arc<T>`, you can use /// [`Yoke::wrap_cart_in_arc()`] to wrap it. /// + /// ✨ *Enabled with the `alloc` Cargo feature.* + /// /// # Example /// /// ```rust @@ -937,8 +976,6 @@ impl<Y: for<'a> Yokeable<'a>, C: 'static + Sized + Send + Sync> Yoke<Y, Arc<C>> /// /// // Now erased1 and erased2 have the same type! /// ``` - /// - /// Available with the `"alloc"` Cargo feature enabled. pub fn erase_arc_cart(self) -> Yoke<Y, ErasedArcCart> { unsafe { // safe because the cart is preserved, just @@ -962,6 +999,8 @@ impl<Y: for<'a> Yokeable<'a>, C: 'static + Sized> Yoke<Y, Box<C>> { /// In case the cart type `C` is not already `Box<T>`, you can use /// [`Yoke::wrap_cart_in_box()`] to wrap it. /// + /// ✨ *Enabled with the `alloc` Cargo feature.* + /// /// # Example /// /// ```rust @@ -983,8 +1022,6 @@ impl<Y: for<'a> Yokeable<'a>, C: 'static + Sized> Yoke<Y, Box<C>> { /// /// // Now erased1 and erased2 have the same type! /// ``` - /// - /// Available with the `"alloc"` Cargo feature enabled. pub fn erase_box_cart(self) -> Yoke<Y, ErasedBoxCart> { unsafe { // safe because the cart is preserved, just @@ -999,7 +1036,7 @@ impl<Y: for<'a> Yokeable<'a>, C> Yoke<Y, C> { /// Helper function allowing one to wrap the cart type `C` in a `Box<T>`. /// Can be paired with [`Yoke::erase_box_cart()`] /// - /// Available with the `"alloc"` Cargo feature enabled. + /// ✨ *Enabled with the `alloc` Cargo feature.* #[inline] pub fn wrap_cart_in_box(self) -> Yoke<Y, Box<C>> { unsafe { @@ -1011,7 +1048,7 @@ impl<Y: for<'a> Yokeable<'a>, C> Yoke<Y, C> { /// Can be paired with [`Yoke::erase_rc_cart()`], or generally used /// to make the [`Yoke`] cloneable. /// - /// Available with the `"alloc"` Cargo feature enabled. + /// ✨ *Enabled with the `alloc` Cargo feature.* #[inline] pub fn wrap_cart_in_rc(self) -> Yoke<Y, Rc<C>> { unsafe { @@ -1023,7 +1060,7 @@ impl<Y: for<'a> Yokeable<'a>, C> Yoke<Y, C> { /// Can be paired with [`Yoke::erase_arc_cart()`], or generally used /// to make the [`Yoke`] cloneable. /// - /// Available with the `"alloc"` Cargo feature enabled. + /// ✨ *Enabled with the `alloc` Cargo feature.* #[inline] pub fn wrap_cart_in_arc(self) -> Yoke<Y, Arc<C>> { unsafe { diff --git a/vendor/yoke/tests/bincode.rs b/vendor/yoke/tests/bincode.rs new file mode 100644 index 000000000..7211e46ff --- /dev/null +++ b/vendor/yoke/tests/bincode.rs @@ -0,0 +1,83 @@ +// 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 ). + +// This test is a duplicate of one of the doctests, but is written separately +// since `cargo miri test` doesn't work on doctests yet + +use std::borrow::Cow; +use std::mem; +use std::rc::Rc; +use yoke::{Yoke, Yokeable}; + +fn load_from_cache(_filename: &str) -> Rc<[u8]> { + // dummy implementation + Rc::new([0x5, 0, 0, 0, 0, 0, 0, 0, 0x68, 0x65, 0x6c, 0x6c, 0x6f]) +} + +fn load_object(filename: &str) -> Yoke<Bar<'static>, Rc<[u8]>> { + let rc: Rc<[u8]> = load_from_cache(filename); + Yoke::<Bar<'static>, Rc<[u8]>>::attach_to_cart(rc, |data: &[u8]| { + // A real implementation would properly deserialize `Bar` as a whole + Bar { + numbers: Cow::Borrowed(bincode::deserialize(data).unwrap()), + string: Cow::Borrowed(bincode::deserialize(data).unwrap()), + owned: Vec::new(), + } + }) +} + +// also implements Yokeable +struct Bar<'a> { + numbers: Cow<'a, [u8]>, + string: Cow<'a, str>, + owned: Vec<u8>, +} + +unsafe impl<'a> Yokeable<'a> for Bar<'static> { + type Output = Bar<'a>; + #[inline] + fn transform(&'a self) -> &'a Bar<'a> { + self + } + #[inline] + fn transform_owned(self) -> Bar<'a> { + self + } + #[inline] + unsafe fn make(from: Bar<'a>) -> Self { + let ret = mem::transmute_copy(&from); + mem::forget(from); + ret + } + #[inline] + fn transform_mut<F>(&'a mut self, f: F) + where + F: 'static + FnOnce(&'a mut Self::Output), + { + unsafe { f(mem::transmute(self)) } + } +} + +#[test] +fn test_load() { + // `load_object()` deserializes an object from a file + let mut bar = load_object("filename.bincode"); + assert_eq!(bar.get().string, "hello"); + assert!(matches!(bar.get().string, Cow::Borrowed(_))); + assert_eq!(&*bar.get().numbers, &[0x68, 0x65, 0x6c, 0x6c, 0x6f]); + assert!(matches!(bar.get().numbers, Cow::Borrowed(_))); + assert_eq!(&*bar.get().owned, &[]); + + bar.with_mut(|bar| { + bar.string.to_mut().push_str(" world"); + bar.owned.extend_from_slice(&[1, 4, 1, 5, 9]); + }); + + assert_eq!(bar.get().string, "hello world"); + assert!(matches!(bar.get().string, Cow::Owned(_))); + assert_eq!(&*bar.get().owned, &[1, 4, 1, 5, 9]); + // Unchanged and still Cow::Borrowed + assert_eq!(&*bar.get().numbers, &[0x68, 0x65, 0x6c, 0x6c, 0x6f]); + assert!(matches!(bar.get().numbers, Cow::Borrowed(_))); +} diff --git a/vendor/yoke/tests/miri.rs b/vendor/yoke/tests/miri.rs new file mode 100644 index 000000000..0b92af2cc --- /dev/null +++ b/vendor/yoke/tests/miri.rs @@ -0,0 +1,15 @@ +// 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 ). + +use yoke::Yoke; + +// Test for strong protection, should pass under miri with -Zmiri-retag-fields +// See https://github.com/unicode-org/icu4x/issues/3696 + +fn example(_: Yoke<&'static [u8], Vec<u8>>) {} + +#[test] +fn run_test() { + example(Yoke::attach_to_cart(vec![0, 1, 2], |data| data)); +} |