+145
| # This file is automatically @generated by Cargo. | ||
| # It is not intended for manual editing. | ||
| version = 3 | ||
| [[package]] | ||
| name = "bincode" | ||
| version = "1.3.3" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" | ||
| dependencies = [ | ||
| "serde", | ||
| ] | ||
| [[package]] | ||
| name = "cobs" | ||
| version = "0.2.3" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" | ||
| [[package]] | ||
| name = "postcard" | ||
| version = "1.1.1" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "170a2601f67cc9dba8edd8c4870b15f71a6a2dc196daec8c83f72b59dff628a8" | ||
| dependencies = [ | ||
| "cobs", | ||
| "serde", | ||
| ] | ||
| [[package]] | ||
| name = "proc-macro2" | ||
| version = "1.0.93" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" | ||
| dependencies = [ | ||
| "unicode-ident", | ||
| ] | ||
| [[package]] | ||
| name = "quote" | ||
| version = "1.0.38" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" | ||
| dependencies = [ | ||
| "proc-macro2", | ||
| ] | ||
| [[package]] | ||
| name = "serde" | ||
| version = "1.0.218" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" | ||
| dependencies = [ | ||
| "serde_derive", | ||
| ] | ||
| [[package]] | ||
| name = "serde_derive" | ||
| version = "1.0.218" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" | ||
| dependencies = [ | ||
| "proc-macro2", | ||
| "quote", | ||
| "syn", | ||
| ] | ||
| [[package]] | ||
| name = "stable_deref_trait" | ||
| version = "1.2.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" | ||
| [[package]] | ||
| name = "syn" | ||
| version = "2.0.98" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" | ||
| dependencies = [ | ||
| "proc-macro2", | ||
| "quote", | ||
| "unicode-ident", | ||
| ] | ||
| [[package]] | ||
| name = "synstructure" | ||
| version = "0.13.1" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" | ||
| dependencies = [ | ||
| "proc-macro2", | ||
| "quote", | ||
| "syn", | ||
| ] | ||
| [[package]] | ||
| name = "unicode-ident" | ||
| version = "1.0.17" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" | ||
| [[package]] | ||
| name = "yoke" | ||
| version = "0.8.0" | ||
| dependencies = [ | ||
| "bincode", | ||
| "postcard", | ||
| "serde", | ||
| "stable_deref_trait", | ||
| "yoke-derive", | ||
| "zerofrom", | ||
| ] | ||
| [[package]] | ||
| name = "yoke-derive" | ||
| version = "0.8.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" | ||
| dependencies = [ | ||
| "proc-macro2", | ||
| "quote", | ||
| "syn", | ||
| "synstructure", | ||
| ] | ||
| [[package]] | ||
| name = "zerofrom" | ||
| version = "0.1.5" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" | ||
| dependencies = [ | ||
| "zerofrom-derive", | ||
| ] | ||
| [[package]] | ||
| name = "zerofrom-derive" | ||
| version = "0.1.5" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" | ||
| dependencies = [ | ||
| "proc-macro2", | ||
| "quote", | ||
| "syn", | ||
| "synstructure", | ||
| ] |
| { | ||
| "git": { | ||
| "sha1": "6bd4893cc44c2ca2718de47a119a31cc40045fe5" | ||
| "sha1": "f4290a877dfcb0f87cad6de4abdd65f0cbb33c9c" | ||
| }, | ||
| "path_in_vcs": "utils/yoke" | ||
| } |
+22
-21
@@ -14,5 +14,5 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO | ||
| edition = "2021" | ||
| rust-version = "1.71.1" | ||
| rust-version = "1.81" | ||
| name = "yoke" | ||
| version = "0.7.5" | ||
| version = "0.8.0" | ||
| authors = ["Manish Goregaokar <manishsmail@gmail.com>"] | ||
@@ -30,2 +30,3 @@ build = false | ||
| ] | ||
| autolib = false | ||
| autobins = false | ||
@@ -62,2 +63,19 @@ autoexamples = false | ||
| [features] | ||
| alloc = [ | ||
| "stable_deref_trait/alloc", | ||
| "serde?/alloc", | ||
| "zerofrom/alloc", | ||
| ] | ||
| default = [ | ||
| "alloc", | ||
| "zerofrom", | ||
| ] | ||
| derive = [ | ||
| "dep:yoke-derive", | ||
| "zerofrom/derive", | ||
| ] | ||
| serde = ["dep:serde"] | ||
| zerofrom = ["dep:zerofrom"] | ||
| [lib] | ||
@@ -85,3 +103,3 @@ name = "yoke" | ||
| [dependencies.yoke-derive] | ||
| version = "0.7.5" | ||
| version = "0.8.0" | ||
| optional = true | ||
@@ -99,3 +117,3 @@ default-features = false | ||
| [dev-dependencies.postcard] | ||
| version = "1.0.1" | ||
| version = "1.0.3" | ||
| default-features = false | ||
@@ -106,18 +124,1 @@ | ||
| default-features = false | ||
| [features] | ||
| alloc = [ | ||
| "stable_deref_trait/alloc", | ||
| "serde?/alloc", | ||
| "zerofrom/alloc", | ||
| ] | ||
| default = [ | ||
| "alloc", | ||
| "zerofrom", | ||
| ] | ||
| derive = [ | ||
| "dep:yoke-derive", | ||
| "zerofrom/derive", | ||
| ] | ||
| serde = ["dep:serde"] | ||
| zerofrom = ["dep:zerofrom"] |
+2
-0
@@ -59,2 +59,3 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| C1: Deref<Target = T>, | ||
| T: ?Sized, | ||
| { | ||
@@ -78,2 +79,3 @@ type Target = T; | ||
| C1: Deref<Target = T>, | ||
| T: ?Sized, | ||
| { | ||
@@ -80,0 +82,0 @@ } |
+2
-2
@@ -28,3 +28,3 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| // https://github.com/unicode-org/icu4x/blob/main/documents/process/boilerplate.md#library-annotations | ||
| #![cfg_attr(all(not(test), not(doc)), no_std)] | ||
| #![cfg_attr(not(any(test, doc)), no_std)] | ||
| # makes it tricky to add | ||
| /// trait bounds on `Yokeable::Output`. For more information and for workarounds, see | ||
| /// [`crate::trait_hack`]. | ||
| /// | ||
| /// # Implementation example | ||
@@ -53,0 +47,0 @@ /// |
+2
-15
@@ -5,3 +5,2 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| use crate::trait_hack::YokeTraitHack; | ||
| use crate::Yoke; | ||
@@ -15,16 +14,6 @@ use crate::Yokeable; | ||
| impl<'zf, C: ?Sized, T> ZeroFrom<'zf, C> for YokeTraitHack<T> | ||
| where | ||
| T: ZeroFrom<'zf, C>, | ||
| { | ||
| #[inline] | ||
| fn zero_from(cart: &'zf C) -> Self { | ||
| YokeTraitHack(T::zero_from(cart)) | ||
| } | ||
| } | ||
| impl<Y, C> Yoke<Y, C> | ||
| where | ||
| Y: for<'a> Yokeable<'a>, | ||
| for<'a> YokeTraitHack<<Y as Yokeable<'a>>::Output>: ZeroFrom<'a, <C as Deref>::Target>, | ||
| for<'a> <Y as Yokeable<'a>>::Output: ZeroFrom<'a, <C as Deref>::Target>, | ||
| C: StableDeref + Deref, | ||
@@ -55,6 +44,4 @@ <C as Deref>::Target: 'static, | ||
| pub fn attach_to_zero_copy_cart(cart: C) -> Self { | ||
| Yoke::<Y, C>::attach_to_cart(cart, |c| { | ||
| YokeTraitHack::<<Y as Yokeable>::Output>::zero_from(c).0 | ||
| }) | ||
| Yoke::<Y, C>::attach_to_cart(cart, |c| <Y as Yokeable>::Output::zero_from(c)) | ||
| } | ||
| } |
| // 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 ). | ||
| //! Workarounds for adding trait bounds to `yoke` objects. | ||
| //! | ||
| //! # Trait bounds in Yoke | ||
| //! | ||
| //! [Compiler bug #89196](https://github.com/rust-lang/rust/issues/89196) makes it tricky to add | ||
| //! trait bounds involving `yoke` types. | ||
| //! | ||
| //! For example, you may want to write: | ||
| //! | ||
| //! `where for<'a> <Y as Yokeable<'a>>::Output: MyTrait` | ||
| //! | ||
| //! The above trait bound will compile, but at call sites, you get errors such as: | ||
| //! | ||
| //! > the trait `for<'de> MyTrait` is not implemented for `<Y as Yokeable<'de>>::Output` | ||
| //! | ||
| //! There are two known workarounds: | ||
| //! | ||
| //! 1. If the trait is well-defined on references, like `Debug`, bind the trait to a reference: | ||
| //! `where for<'a> &'a <Y as Yokeable<'a>>::Output: MyTrait` | ||
| //! 2. If the trait involves `Self`, like `Clone`, use [`YokeTraitHack`]: | ||
| //! `where for<'a> YokeTraitHack<<Y as Yokeable<'a>>::Output>: MyTrait` | ||
| //! | ||
| //! # Examples | ||
| //! | ||
| //! Code that does not compile ([playground](https://play.rust-lang.org/?version=beta&mode=debug&edition=2018&gist=ebbda5b15a398d648bdff9e439b27dc0)): | ||
| //! | ||
| //! ```compile_fail | ||
| //! # this compiles in 1.78+, so this text will make it fail | ||
| //! use yoke::*; | ||
| //! | ||
| //! trait MiniDataMarker { | ||
| //! type Yokeable: for<'a> Yokeable<'a>; | ||
| //! } | ||
| //! | ||
| //! struct MiniDataPayload<M> | ||
| //! where | ||
| //! M: MiniDataMarker | ||
| //! { | ||
| //! pub yoke: Yoke<M::Yokeable, ()>, | ||
| //! } | ||
| //! | ||
| //! impl<M> Clone for MiniDataPayload<M> | ||
| //! where | ||
| //! M: MiniDataMarker, | ||
| //! for<'a> <M::Yokeable as Yokeable<'a>>::Output: Clone, | ||
| //! { | ||
| //! fn clone(&self) -> Self { | ||
| //! unimplemented!() | ||
| //! } | ||
| //! } | ||
| //! | ||
| //! trait MiniDataProvider<M> | ||
| //! where | ||
| //! M: MiniDataMarker | ||
| //! { | ||
| //! fn mini_load_data(&self) -> MiniDataPayload<M>; | ||
| //! } | ||
| //! | ||
| //! struct MiniStructProvider<M> | ||
| //! where | ||
| //! M: MiniDataMarker, | ||
| //! { | ||
| //! pub payload: MiniDataPayload<M>, | ||
| //! } | ||
| //! | ||
| //! impl<M> MiniDataProvider<M> for MiniStructProvider<M> | ||
| //! where | ||
| //! M: MiniDataMarker, | ||
| //! for<'a> <M::Yokeable as Yokeable<'a>>::Output: Clone, | ||
| //! { | ||
| //! fn mini_load_data(&self) -> MiniDataPayload<M> { | ||
| //! self.payload.clone() | ||
| //! } | ||
| //! } | ||
| //! | ||
| //! #[derive(Clone)] | ||
| //! struct SimpleStruct(pub u32); | ||
| //! | ||
| //! unsafe impl<'a> Yokeable<'a> for SimpleStruct { | ||
| //! // (not shown; see `Yokeable` for examples) | ||
| //! # type Output = SimpleStruct; | ||
| //! # fn transform(&'a self) -> &'a Self::Output { | ||
| //! # self | ||
| //! # } | ||
| //! # fn transform_owned(self) -> Self::Output { | ||
| //! # self | ||
| //! # } | ||
| //! # unsafe fn make(from: Self::Output) -> Self { | ||
| //! # std::mem::transmute(from) | ||
| //! # } | ||
| //! # fn transform_mut<F>(&'a mut self, f: F) | ||
| //! # where | ||
| //! # F: 'static + for<'b> FnOnce(&'b mut Self::Output), | ||
| //! # { | ||
| //! # unsafe { | ||
| //! # f(std::mem::transmute::<&'a mut Self, &'a mut Self::Output>( | ||
| //! # self, | ||
| //! # )) | ||
| //! # } | ||
| //! # } | ||
| //! } | ||
| //! | ||
| //! impl MiniDataMarker for SimpleStruct { | ||
| //! type DataStruct = SimpleStruct; | ||
| //! } | ||
| //! | ||
| //! let provider = MiniStructProvider { | ||
| //! payload: MiniDataPayload { | ||
| //! yoke: Yoke::new_always_owned(SimpleStruct(42)) | ||
| //! } | ||
| //! }; | ||
| //! | ||
| //! // Broken: | ||
| //! // "method cannot be called on `MiniStructProvider<_>` due to unsatisfied trait bounds" | ||
| //! let payload: MiniDataPayload<SimpleStruct> = provider.mini_load_data(); | ||
| //! | ||
| //! // Working: | ||
| //! let payload = MiniDataProvider::<SimpleStruct>::mini_load_data(&provider); | ||
| //! | ||
| //! assert_eq!(payload.yoke.get().0, 42); | ||
| //! ``` | ||
| //! | ||
| //! Example for binding the trait to a reference: | ||
| //! | ||
| //! ``` | ||
| //! use yoke::Yoke; | ||
| //! use yoke::Yokeable; | ||
| //! | ||
| //! // Example trait and struct for illustration purposes: | ||
| //! trait MyTrait { | ||
| //! fn demo(&self) -> u32; | ||
| //! } | ||
| //! struct MyStruct(u32); | ||
| //! impl MyTrait for MyStruct { | ||
| //! fn demo(&self) -> u32 { | ||
| //! self.0 | ||
| //! } | ||
| //! } | ||
| //! unsafe impl<'a> Yokeable<'a> for MyStruct { | ||
| //! // (not shown; see `Yokeable` for examples) | ||
| //! # type Output = MyStruct; | ||
| //! # fn transform(&'a self) -> &'a Self::Output { | ||
| //! # self | ||
| //! # } | ||
| //! # fn transform_owned(self) -> Self::Output { | ||
| //! # self | ||
| //! # } | ||
| //! # unsafe fn make(from: Self::Output) -> Self { | ||
| //! # std::mem::transmute(from) | ||
| //! # } | ||
| //! # fn transform_mut<F>(&'a mut self, f: F) | ||
| //! # where | ||
| //! # F: 'static + for<'b> FnOnce(&'b mut Self::Output), | ||
| //! # { | ||
| //! # unsafe { | ||
| //! # f(std::mem::transmute::<&'a mut Self, &'a mut Self::Output>( | ||
| //! # self, | ||
| //! # )) | ||
| //! # } | ||
| //! # } | ||
| //! } | ||
| //! | ||
| //! // The trait needs to be defined on references: | ||
| //! impl<'a, T> MyTrait for &'a T | ||
| //! where | ||
| //! T: MyTrait, | ||
| //! { | ||
| //! fn demo(&self) -> u32 { | ||
| //! self.demo() | ||
| //! } | ||
| //! } | ||
| //! | ||
| //! impl<Y, C> MyTrait for Yoke<Y, C> | ||
| //! where | ||
| //! Y: for<'a> Yokeable<'a>, | ||
| //! for<'a> &'a <Y as Yokeable<'a>>::Output: MyTrait, | ||
| //! { | ||
| //! fn demo(&self) -> u32 { | ||
| //! self.get().demo() | ||
| //! } | ||
| //! } | ||
| //! | ||
| //! fn example() { | ||
| //! let y = Yoke::<MyStruct, ()>::new_always_owned(MyStruct(42)); | ||
| //! let _: &dyn MyTrait = &y; | ||
| //! } | ||
| //! ``` | ||
| //! | ||
| //! Example for using [`YokeTraitHack`]: | ||
| //! | ||
| //! ``` | ||
| //! use std::rc::Rc; | ||
| //! use yoke::trait_hack::YokeTraitHack; | ||
| //! use yoke::Yoke; | ||
| //! use yoke::Yokeable; | ||
| //! | ||
| //! // Example trait and struct for illustration purposes: | ||
| //! trait MyTrait { | ||
| //! fn demo(data: u32) -> Self; | ||
| //! } | ||
| //! struct MyStruct(u32); | ||
| //! impl MyTrait for MyStruct { | ||
| //! fn demo(data: u32) -> Self { | ||
| //! Self(data) | ||
| //! } | ||
| //! } | ||
| //! unsafe impl<'a> Yokeable<'a> for MyStruct { | ||
| //! // (not shown; see `Yokeable` for examples) | ||
| //! # type Output = MyStruct; | ||
| //! # fn transform(&'a self) -> &'a Self::Output { | ||
| //! # self | ||
| //! # } | ||
| //! # fn transform_owned(self) -> Self::Output { | ||
| //! # self | ||
| //! # } | ||
| //! # unsafe fn make(from: Self::Output) -> Self { | ||
| //! # std::mem::transmute(from) | ||
| //! # } | ||
| //! # fn transform_mut<F>(&'a mut self, f: F) | ||
| //! # where | ||
| //! # F: 'static + for<'b> FnOnce(&'b mut Self::Output), | ||
| //! # { | ||
| //! # unsafe { | ||
| //! # f(std::mem::transmute::<&'a mut Self, &'a mut Self::Output>( | ||
| //! # self, | ||
| //! # )) | ||
| //! # } | ||
| //! # } | ||
| //! } | ||
| //! | ||
| //! // The trait needs to be defined on YokeTraitHack: | ||
| //! impl<'a, T> MyTrait for YokeTraitHack<T> | ||
| //! where | ||
| //! T: MyTrait, | ||
| //! { | ||
| //! fn demo(data: u32) -> Self { | ||
| //! YokeTraitHack(T::demo(data)) | ||
| //! } | ||
| //! } | ||
| //! | ||
| //! impl<Y> MyTrait for Yoke<Y, Rc<u32>> | ||
| //! where | ||
| //! Y: for<'a> Yokeable<'a>, | ||
| //! for<'a> YokeTraitHack<<Y as Yokeable<'a>>::Output>: MyTrait, | ||
| //! { | ||
| //! fn demo(data: u32) -> Self { | ||
| //! let rc_u32: Rc<u32> = Rc::new(data); | ||
| //! Yoke::attach_to_cart(rc_u32, |u| { | ||
| //! YokeTraitHack::<<Y as Yokeable>::Output>::demo(*u).0 | ||
| //! }) | ||
| //! } | ||
| //! } | ||
| //! | ||
| //! fn example() { | ||
| //! let _ = Yoke::<MyStruct, Rc<u32>>::demo(42); | ||
| //! } | ||
| //! ``` | ||
| use core::mem; | ||
| /// A wrapper around a type `T`, forwarding trait calls down to the inner type. | ||
| /// | ||
| /// `YokeTraitHack` supports [`Clone`], [`PartialEq`], [`Eq`], and [`serde::Deserialize`] out of | ||
| /// the box. Other traits can be implemented by the caller. | ||
| /// | ||
| /// For more information, see the module-level documentation. | ||
| /// | ||
| /// # Example | ||
| /// | ||
| /// Using `YokeTraitHack` as a type bound in a function comparing two `Yoke`s: | ||
| /// | ||
| /// ``` | ||
| /// use yoke::trait_hack::YokeTraitHack; | ||
| /// use yoke::*; | ||
| /// | ||
| /// fn compare_yokes<Y, C1, C2>(y1: Yoke<Y, C1>, y2: Yoke<Y, C2>) -> bool | ||
| /// where | ||
| /// Y: for<'a> Yokeable<'a>, | ||
| /// for<'a> YokeTraitHack<<Y as Yokeable<'a>>::Output>: PartialEq, | ||
| /// { | ||
| /// YokeTraitHack(y1.get()).into_ref() == YokeTraitHack(y2.get()).into_ref() | ||
| /// } | ||
| /// ``` | ||
| #[repr(transparent)] | ||
| #[derive(Clone, PartialEq, Eq, Debug)] | ||
| #[allow(clippy::exhaustive_structs)] // newtype | ||
| pub struct YokeTraitHack<T>(pub T); | ||
| impl<'a, T> YokeTraitHack<&'a T> { | ||
| /// Converts from `YokeTraitHack<&T>` to `&YokeTraitHack<T>`. | ||
| /// | ||
| /// This is safe because `YokeTraitHack` is `repr(transparent)`. | ||
| /// | ||
| /// This method is required to implement `Clone` on `Yoke`. | ||
| pub fn into_ref(self) -> &'a YokeTraitHack<T> { | ||
| // Safety: YokeTraitHack is repr(transparent) so it's always safe | ||
| // to transmute YTH<&T> to &YTH<T> | ||
| unsafe { mem::transmute::<YokeTraitHack<&T>, &YokeTraitHack<T>>(self) } | ||
| } | ||
| } | ||
| // This is implemented manually to avoid the serde derive dependency. | ||
| #[cfg(feature = "serde")] | ||
| impl<'de, T> serde::de::Deserialize<'de> for YokeTraitHack<T> | ||
| where | ||
| T: serde::de::Deserialize<'de>, | ||
| { | ||
| #[inline] | ||
| fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | ||
| where | ||
| D: serde::de::Deserializer<'de>, | ||
| { | ||
| T::deserialize(deserializer).map(YokeTraitHack) | ||
| } | ||
| } |
Sorry, the diff of this file is not supported yet