Coverage Report

Created: 2026-01-09 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/zerovec-0.11.5/src/yoke_impls.rs
Line
Count
Source
1
// This file is part of ICU4X. For terms of use, please see the file
2
// called LICENSE at the top level of the ICU4X source tree
3
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4
5
// This way we can copy-paste Yokeable impls
6
#![allow(unknown_lints)] // forgetting_copy_types
7
#![allow(renamed_and_removed_lints)] // forgetting_copy_types
8
#![allow(forgetting_copy_types)]
9
#![allow(clippy::forget_copy)]
10
#![allow(clippy::forget_non_drop)]
11
12
#[cfg(feature = "alloc")]
13
use crate::map::ZeroMapBorrowed;
14
#[cfg(feature = "alloc")]
15
use crate::map::ZeroMapKV;
16
#[cfg(feature = "alloc")]
17
use crate::map2d::ZeroMap2dBorrowed;
18
use crate::ule::*;
19
use crate::{VarZeroCow, VarZeroVec, ZeroVec};
20
#[cfg(feature = "alloc")]
21
use crate::{ZeroMap, ZeroMap2d};
22
use core::{mem, ptr};
23
use yoke::*;
24
25
// This impl is similar to the impl on Cow and is safe for the same reasons
26
/// This impl requires enabling the optional `yoke` Cargo feature of the `zerovec` crate
27
unsafe impl<'a, T: 'static + AsULE> Yokeable<'a> for ZeroVec<'static, T> {
28
    type Output = ZeroVec<'a, T>;
29
    #[inline]
30
0
    fn transform(&'a self) -> &'a Self::Output {
31
0
        self
32
0
    }
33
    #[inline]
34
0
    fn transform_owned(self) -> Self::Output {
35
0
        self
36
0
    }
37
    #[inline]
38
0
    unsafe fn make(from: Self::Output) -> Self {
39
0
        debug_assert!(mem::size_of::<Self::Output>() == mem::size_of::<Self>());
40
0
        let from = mem::ManuallyDrop::new(from);
41
0
        let ptr: *const Self = (&*from as *const Self::Output).cast();
42
0
        ptr::read(ptr)
43
0
    }
44
    #[inline]
45
0
    fn transform_mut<F>(&'a mut self, f: F)
46
0
    where
47
0
        F: 'static + for<'b> FnOnce(&'b mut Self::Output),
48
    {
49
0
        unsafe { f(mem::transmute::<&mut Self, &mut Self::Output>(self)) }
50
0
    }
51
}
52
53
// This impl is similar to the impl on Cow and is safe for the same reasons
54
/// This impl requires enabling the optional `yoke` Cargo feature of the `zerovec` crate
55
unsafe impl<'a, T: 'static + VarULE + ?Sized> Yokeable<'a> for VarZeroVec<'static, T> {
56
    type Output = VarZeroVec<'a, T>;
57
    #[inline]
58
0
    fn transform(&'a self) -> &'a Self::Output {
59
0
        self
60
0
    }
61
    #[inline]
62
0
    fn transform_owned(self) -> Self::Output {
63
0
        self
64
0
    }
65
    #[inline]
66
0
    unsafe fn make(from: Self::Output) -> Self {
67
0
        debug_assert!(mem::size_of::<Self::Output>() == mem::size_of::<Self>());
68
0
        let from = mem::ManuallyDrop::new(from);
69
0
        let ptr: *const Self = (&*from as *const Self::Output).cast();
70
0
        ptr::read(ptr)
71
0
    }
72
    #[inline]
73
0
    fn transform_mut<F>(&'a mut self, f: F)
74
0
    where
75
0
        F: 'static + for<'b> FnOnce(&'b mut Self::Output),
76
    {
77
0
        unsafe { f(mem::transmute::<&mut Self, &mut Self::Output>(self)) }
78
0
    }
79
}
80
81
// This impl is similar to the impl on Cow and is safe for the same reasons
82
/// This impl requires enabling the optional `yoke` Cargo feature of the `zerovec` crate
83
unsafe impl<'a, T: 'static + ?Sized> Yokeable<'a> for VarZeroCow<'static, T> {
84
    type Output = VarZeroCow<'a, T>;
85
    #[inline]
86
0
    fn transform(&'a self) -> &'a Self::Output {
87
0
        self
88
0
    }
89
    #[inline]
90
0
    fn transform_owned(self) -> Self::Output {
91
0
        self
92
0
    }
93
    #[inline]
94
0
    unsafe fn make(from: Self::Output) -> Self {
95
0
        debug_assert!(mem::size_of::<Self::Output>() == mem::size_of::<Self>());
96
0
        let from = mem::ManuallyDrop::new(from);
97
0
        let ptr: *const Self = (&*from as *const Self::Output).cast();
98
0
        ptr::read(ptr)
99
0
    }
100
    #[inline]
101
0
    fn transform_mut<F>(&'a mut self, f: F)
102
0
    where
103
0
        F: 'static + for<'b> FnOnce(&'b mut Self::Output),
104
    {
105
0
        unsafe { f(mem::transmute::<&mut Self, &mut Self::Output>(self)) }
106
0
    }
107
}
108
109
/// This impl requires enabling the optional `yoke` Cargo feature of the `zerovec` crate
110
#[cfg(feature = "alloc")]
111
unsafe impl<'a, K, V> Yokeable<'a> for ZeroMap<'static, K, V>
112
where
113
    K: 'static + for<'b> ZeroMapKV<'b> + ?Sized,
114
    V: 'static + for<'b> ZeroMapKV<'b> + ?Sized,
115
    <K as ZeroMapKV<'static>>::Container: for<'b> Yokeable<'b>,
116
    <V as ZeroMapKV<'static>>::Container: for<'b> Yokeable<'b>,
117
{
118
    type Output = ZeroMap<'a, K, V>;
119
    #[inline]
120
    fn transform(&'a self) -> &'a Self::Output {
121
        unsafe {
122
            // Unfortunately, because K and V are generic, rustc is
123
            // unaware that these are covariant types, and cannot perform this cast automatically.
124
            // We transmute it instead, and enforce the lack of a lifetime with the `K, V: 'static` bound
125
            mem::transmute::<&Self, &Self::Output>(self)
126
        }
127
    }
128
    #[inline]
129
    fn transform_owned(self) -> Self::Output {
130
        debug_assert!(mem::size_of::<Self::Output>() == mem::size_of::<Self>());
131
        unsafe {
132
            // Similar problem as transform(), but we need to use ptr::read since
133
            // the compiler isn't sure of the sizes
134
            let this = mem::ManuallyDrop::new(self);
135
            let ptr: *const Self::Output = (&*this as *const Self).cast();
136
            ptr::read(ptr)
137
        }
138
    }
139
    #[inline]
140
    unsafe fn make(from: Self::Output) -> Self {
141
        debug_assert!(mem::size_of::<Self::Output>() == mem::size_of::<Self>());
142
        let from = mem::ManuallyDrop::new(from);
143
        let ptr: *const Self = (&*from as *const Self::Output).cast();
144
        ptr::read(ptr)
145
    }
146
    #[inline]
147
    fn transform_mut<F>(&'a mut self, f: F)
148
    where
149
        F: 'static + for<'b> FnOnce(&'b mut Self::Output),
150
    {
151
        unsafe { f(mem::transmute::<&mut Self, &mut Self::Output>(self)) }
152
    }
153
}
154
155
/// This impl requires enabling the optional `yoke` Cargo feature of the `zerovec` crate
156
#[cfg(feature = "alloc")]
157
unsafe impl<'a, K, V> Yokeable<'a> for ZeroMapBorrowed<'static, K, V>
158
where
159
    K: 'static + for<'b> ZeroMapKV<'b> + ?Sized,
160
    V: 'static + for<'b> ZeroMapKV<'b> + ?Sized,
161
    &'static <K as ZeroMapKV<'static>>::Slice: for<'b> Yokeable<'b>,
162
    &'static <V as ZeroMapKV<'static>>::Slice: for<'b> Yokeable<'b>,
163
{
164
    type Output = ZeroMapBorrowed<'a, K, V>;
165
    #[inline]
166
    fn transform(&'a self) -> &'a Self::Output {
167
        unsafe {
168
            // Unfortunately, because K and V are generic, rustc is
169
            // unaware that these are covariant types, and cannot perform this cast automatically.
170
            // We transmute it instead, and enforce the lack of a lifetime with the `K, V: 'static` bound
171
            mem::transmute::<&Self, &Self::Output>(self)
172
        }
173
    }
174
    #[inline]
175
    fn transform_owned(self) -> Self::Output {
176
        debug_assert!(mem::size_of::<Self::Output>() == mem::size_of::<Self>());
177
        unsafe {
178
            // Similar problem as transform(), but we need to use ptr::read since
179
            // the compiler isn't sure of the sizes
180
            let this = mem::ManuallyDrop::new(self);
181
            let ptr: *const Self::Output = (&*this as *const Self).cast();
182
            ptr::read(ptr)
183
        }
184
    }
185
    #[inline]
186
    unsafe fn make(from: Self::Output) -> Self {
187
        debug_assert!(mem::size_of::<Self::Output>() == mem::size_of::<Self>());
188
        let from = mem::ManuallyDrop::new(from);
189
        let ptr: *const Self = (&*from as *const Self::Output).cast();
190
        ptr::read(ptr)
191
    }
192
    #[inline]
193
    fn transform_mut<F>(&'a mut self, f: F)
194
    where
195
        F: 'static + for<'b> FnOnce(&'b mut Self::Output),
196
    {
197
        unsafe { f(mem::transmute::<&mut Self, &mut Self::Output>(self)) }
198
    }
199
}
200
201
/// This impl requires enabling the optional `yoke` Cargo feature of the `zerovec` crate
202
#[cfg(feature = "alloc")]
203
unsafe impl<'a, K0, K1, V> Yokeable<'a> for ZeroMap2d<'static, K0, K1, V>
204
where
205
    K0: 'static + for<'b> ZeroMapKV<'b> + ?Sized,
206
    K1: 'static + for<'b> ZeroMapKV<'b> + ?Sized,
207
    V: 'static + for<'b> ZeroMapKV<'b> + ?Sized,
208
    <K0 as ZeroMapKV<'static>>::Container: for<'b> Yokeable<'b>,
209
    <K1 as ZeroMapKV<'static>>::Container: for<'b> Yokeable<'b>,
210
    <V as ZeroMapKV<'static>>::Container: for<'b> Yokeable<'b>,
211
{
212
    type Output = ZeroMap2d<'a, K0, K1, V>;
213
    #[inline]
214
    fn transform(&'a self) -> &'a Self::Output {
215
        unsafe {
216
            // Unfortunately, because K and V are generic, rustc is
217
            // unaware that these are covariant types, and cannot perform this cast automatically.
218
            // We transmute it instead, and enforce the lack of a lifetime with the `K0, K1, V: 'static` bound
219
            mem::transmute::<&Self, &Self::Output>(self)
220
        }
221
    }
222
    #[inline]
223
    fn transform_owned(self) -> Self::Output {
224
        debug_assert!(mem::size_of::<Self::Output>() == mem::size_of::<Self>());
225
        unsafe {
226
            // Similar problem as transform(), but we need to use ptr::read since
227
            // the compiler isn't sure of the sizes
228
            let this = mem::ManuallyDrop::new(self);
229
            let ptr: *const Self::Output = (&*this as *const Self).cast();
230
            ptr::read(ptr)
231
        }
232
    }
233
    #[inline]
234
    unsafe fn make(from: Self::Output) -> Self {
235
        debug_assert!(mem::size_of::<Self::Output>() == mem::size_of::<Self>());
236
        let from = mem::ManuallyDrop::new(from);
237
        let ptr: *const Self = (&*from as *const Self::Output).cast();
238
        ptr::read(ptr)
239
    }
240
    #[inline]
241
    fn transform_mut<F>(&'a mut self, f: F)
242
    where
243
        F: 'static + for<'b> FnOnce(&'b mut Self::Output),
244
    {
245
        unsafe { f(mem::transmute::<&mut Self, &mut Self::Output>(self)) }
246
    }
247
}
248
249
/// This impl requires enabling the optional `yoke` Cargo feature of the `zerovec` crate
250
#[cfg(feature = "alloc")]
251
unsafe impl<'a, K0, K1, V> Yokeable<'a> for ZeroMap2dBorrowed<'static, K0, K1, V>
252
where
253
    K0: 'static + for<'b> ZeroMapKV<'b> + ?Sized,
254
    K1: 'static + for<'b> ZeroMapKV<'b> + ?Sized,
255
    V: 'static + for<'b> ZeroMapKV<'b> + ?Sized,
256
    &'static <K0 as ZeroMapKV<'static>>::Slice: for<'b> Yokeable<'b>,
257
    &'static <K1 as ZeroMapKV<'static>>::Slice: for<'b> Yokeable<'b>,
258
    &'static <V as ZeroMapKV<'static>>::Slice: for<'b> Yokeable<'b>,
259
{
260
    type Output = ZeroMap2dBorrowed<'a, K0, K1, V>;
261
    #[inline]
262
    fn transform(&'a self) -> &'a Self::Output {
263
        unsafe {
264
            // Unfortunately, because K and V are generic, rustc is
265
            // unaware that these are covariant types, and cannot perform this cast automatically.
266
            // We transmute it instead, and enforce the lack of a lifetime with the `K0, K1, V: 'static` bound
267
            mem::transmute::<&Self, &Self::Output>(self)
268
        }
269
    }
270
    #[inline]
271
    fn transform_owned(self) -> Self::Output {
272
        debug_assert!(mem::size_of::<Self::Output>() == mem::size_of::<Self>());
273
        unsafe {
274
            // Similar problem as transform(), but we need to use ptr::read since
275
            // the compiler isn't sure of the sizes
276
            let this = mem::ManuallyDrop::new(self);
277
            let ptr: *const Self::Output = (&*this as *const Self).cast();
278
            ptr::read(ptr)
279
        }
280
    }
281
    #[inline]
282
    unsafe fn make(from: Self::Output) -> Self {
283
        debug_assert!(mem::size_of::<Self::Output>() == mem::size_of::<Self>());
284
        let from = mem::ManuallyDrop::new(from);
285
        let ptr: *const Self = (&*from as *const Self::Output).cast();
286
        ptr::read(ptr)
287
    }
288
    #[inline]
289
    fn transform_mut<F>(&'a mut self, f: F)
290
    where
291
        F: 'static + for<'b> FnOnce(&'b mut Self::Output),
292
    {
293
        unsafe { f(mem::transmute::<&mut Self, &mut Self::Output>(self)) }
294
    }
295
}
296
297
#[cfg(test)]
298
#[allow(non_camel_case_types, non_snake_case)]
299
mod test {
300
    use super::*;
301
    use crate::{VarZeroSlice, ZeroSlice};
302
    use databake::*;
303
304
    // Note: The following derives cover Yoke as well as Serde and databake. These may partially
305
    // duplicate tests elsewhere in this crate, but they are here for completeness.
306
307
    #[derive(yoke::Yokeable, zerofrom::ZeroFrom)]
308
    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
309
    #[cfg_attr(feature = "databake", derive(databake::Bake))]
310
    #[cfg_attr(feature = "databake", databake(path = zerovec::yoke_impls::test))]
311
    struct DeriveTest_ZeroVec<'data> {
312
        #[cfg_attr(feature = "serde", serde(borrow))]
313
        pub _data: ZeroVec<'data, u16>,
314
    }
315
316
    #[test]
317
    fn bake_ZeroVec() {
318
        test_bake!(
319
            DeriveTest_ZeroVec<'static>,
320
            crate::yoke_impls::test::DeriveTest_ZeroVec {
321
                _data: crate::ZeroVec::new(),
322
            },
323
            zerovec,
324
        );
325
    }
326
327
    #[derive(yoke::Yokeable)]
328
    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
329
    #[cfg_attr(feature = "databake", derive(databake::Bake))]
330
    #[cfg_attr(feature = "databake", databake(path = zerovec::yoke_impls::test))]
331
    struct DeriveTest_ZeroSlice<'data> {
332
        #[cfg_attr(feature = "serde", serde(borrow))]
333
        pub _data: &'data ZeroSlice<u16>,
334
    }
335
336
    #[test]
337
    fn bake_ZeroSlice() {
338
        test_bake!(
339
            DeriveTest_ZeroSlice<'static>,
340
            crate::yoke_impls::test::DeriveTest_ZeroSlice {
341
                _data: crate::ZeroSlice::new_empty(),
342
            },
343
            zerovec,
344
        );
345
    }
346
347
    #[derive(yoke::Yokeable, zerofrom::ZeroFrom)]
348
    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
349
    #[cfg_attr(feature = "databake", derive(databake::Bake))]
350
    #[cfg_attr(feature = "databake", databake(path = zerovec::yoke_impls::test))]
351
    struct DeriveTest_VarZeroVec<'data> {
352
        #[cfg_attr(feature = "serde", serde(borrow))]
353
        pub _data: VarZeroVec<'data, str>,
354
    }
355
356
    #[test]
357
    fn bake_VarZeroVec() {
358
        test_bake!(
359
            DeriveTest_VarZeroVec<'static>,
360
            crate::yoke_impls::test::DeriveTest_VarZeroVec {
361
                _data: crate::vecs::VarZeroVec16::new(),
362
            },
363
            zerovec,
364
        );
365
    }
366
367
    #[derive(yoke::Yokeable)]
368
    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
369
    #[cfg_attr(feature = "databake", derive(databake::Bake))]
370
    #[cfg_attr(feature = "databake", databake(path = zerovec::yoke_impls::test))]
371
    struct DeriveTest_VarZeroSlice<'data> {
372
        #[cfg_attr(feature = "serde", serde(borrow))]
373
        pub _data: &'data VarZeroSlice<str>,
374
    }
375
376
    #[test]
377
    fn bake_VarZeroSlice() {
378
        test_bake!(
379
            DeriveTest_VarZeroSlice<'static>,
380
            crate::yoke_impls::test::DeriveTest_VarZeroSlice {
381
                _data: crate::vecs::VarZeroSlice16::new_empty()
382
            },
383
            zerovec,
384
        );
385
    }
386
387
    #[derive(yoke::Yokeable, zerofrom::ZeroFrom)]
388
    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
389
    #[cfg_attr(feature = "databake", derive(databake::Bake))]
390
    #[cfg_attr(feature = "databake", databake(path = zerovec::yoke_impls::test))]
391
    #[yoke(prove_covariance_manually)]
392
    struct DeriveTest_ZeroMap<'data> {
393
        #[cfg_attr(feature = "serde", serde(borrow))]
394
        pub _data: ZeroMap<'data, [u8], str>,
395
    }
396
397
    #[test]
398
    fn bake_ZeroMap() {
399
        test_bake!(
400
            DeriveTest_ZeroMap<'static>,
401
            crate::yoke_impls::test::DeriveTest_ZeroMap {
402
                _data: unsafe {
403
                    #[allow(unused_unsafe)]
404
                    crate::ZeroMap::from_parts_unchecked(
405
                        crate::vecs::VarZeroVec16::new(),
406
                        crate::vecs::VarZeroVec16::new(),
407
                    )
408
                },
409
            },
410
            zerovec,
411
        );
412
    }
413
414
    #[derive(yoke::Yokeable)]
415
    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
416
    #[cfg_attr(feature = "databake", derive(databake::Bake))]
417
    #[cfg_attr(feature = "databake", databake(path = zerovec::yoke_impls::test))]
418
    #[yoke(prove_covariance_manually)]
419
    struct DeriveTest_ZeroMapBorrowed<'data> {
420
        #[cfg_attr(feature = "serde", serde(borrow))]
421
        pub _data: ZeroMapBorrowed<'data, [u8], str>,
422
    }
423
424
    #[test]
425
    fn bake_ZeroMapBorrowed() {
426
        test_bake!(
427
            DeriveTest_ZeroMapBorrowed<'static>,
428
            crate::yoke_impls::test::DeriveTest_ZeroMapBorrowed {
429
                _data: unsafe {
430
                    #[allow(unused_unsafe)]
431
                    crate::maps::ZeroMapBorrowed::from_parts_unchecked(
432
                        crate::vecs::VarZeroSlice16::new_empty(),
433
                        crate::vecs::VarZeroSlice16::new_empty(),
434
                    )
435
                },
436
            },
437
            zerovec,
438
        );
439
    }
440
441
    #[derive(yoke::Yokeable, zerofrom::ZeroFrom)]
442
    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
443
    #[cfg_attr(feature = "databake", derive(databake::Bake))]
444
    #[cfg_attr(feature = "databake", databake(path = zerovec::yoke_impls::test))]
445
    #[yoke(prove_covariance_manually)]
446
    struct DeriveTest_ZeroMapWithULE<'data> {
447
        #[cfg_attr(feature = "serde", serde(borrow))]
448
        pub _data: ZeroMap<'data, ZeroSlice<u32>, str>,
449
    }
450
451
    #[test]
452
    fn bake_ZeroMapWithULE() {
453
        test_bake!(
454
            DeriveTest_ZeroMapWithULE<'static>,
455
            crate::yoke_impls::test::DeriveTest_ZeroMapWithULE {
456
                _data: unsafe {
457
                    #[allow(unused_unsafe)]
458
                    crate::ZeroMap::from_parts_unchecked(
459
                        crate::vecs::VarZeroVec16::new(),
460
                        crate::vecs::VarZeroVec16::new(),
461
                    )
462
                },
463
            },
464
            zerovec,
465
        );
466
    }
467
468
    #[derive(yoke::Yokeable, zerofrom::ZeroFrom)]
469
    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
470
    #[cfg_attr(feature = "databake", derive(databake::Bake))]
471
    #[cfg_attr(feature = "databake", databake(path = zerovec::yoke_impls::test))]
472
    #[yoke(prove_covariance_manually)]
473
    struct DeriveTest_ZeroMap2d<'data> {
474
        #[cfg_attr(feature = "serde", serde(borrow))]
475
        pub _data: ZeroMap2d<'data, u16, u16, str>,
476
    }
477
478
    #[test]
479
    fn bake_ZeroMap2d() {
480
        test_bake!(
481
            DeriveTest_ZeroMap2d<'static>,
482
            crate::yoke_impls::test::DeriveTest_ZeroMap2d {
483
                _data: unsafe {
484
                    #[allow(unused_unsafe)]
485
                    crate::ZeroMap2d::from_parts_unchecked(
486
                        crate::ZeroVec::new(),
487
                        crate::ZeroVec::new(),
488
                        crate::ZeroVec::new(),
489
                        crate::vecs::VarZeroVec16::new(),
490
                    )
491
                },
492
            },
493
            zerovec,
494
        );
495
    }
496
497
    #[derive(yoke::Yokeable)]
498
    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
499
    #[cfg_attr(feature = "databake", derive(databake::Bake))]
500
    #[cfg_attr(feature = "databake", databake(path = zerovec::yoke_impls::test))]
501
    #[yoke(prove_covariance_manually)]
502
    struct DeriveTest_ZeroMap2dBorrowed<'data> {
503
        #[cfg_attr(feature = "serde", serde(borrow))]
504
        pub _data: ZeroMap2dBorrowed<'data, u16, u16, str>,
505
    }
506
507
    #[test]
508
    fn bake_ZeroMap2dBorrowed() {
509
        test_bake!(
510
            DeriveTest_ZeroMap2dBorrowed<'static>,
511
            crate::yoke_impls::test::DeriveTest_ZeroMap2dBorrowed {
512
                _data: unsafe {
513
                    #[allow(unused_unsafe)]
514
                    crate::maps::ZeroMap2dBorrowed::from_parts_unchecked(
515
                        crate::ZeroSlice::new_empty(),
516
                        crate::ZeroSlice::new_empty(),
517
                        crate::ZeroSlice::new_empty(),
518
                        crate::vecs::VarZeroSlice16::new_empty(),
519
                    )
520
                },
521
            },
522
            zerovec,
523
        );
524
    }
525
}