1pub mod gc;
2pub mod value;
3
4use crate::{
5 Finalize,
6 lifetime::{
7 Lifetime, LifetimeLazy, LifetimeRef, LifetimeRefMut, ValueReadAccess, ValueWriteAccess,
8 },
9 managed::value::{DynamicManagedValue, ManagedValue},
10 non_zero_alloc, non_zero_dealloc,
11 type_hash::TypeHash,
12};
13use std::{alloc::Layout, mem::MaybeUninit};
14
15#[derive(Default)]
16pub struct Managed<T> {
17 lifetime: Lifetime,
18 data: T,
19}
20
21impl<T> Managed<T> {
22 pub fn new(data: T) -> Self {
23 Self {
24 lifetime: Default::default(),
25 data,
26 }
27 }
28
29 pub fn new_raw(data: T, lifetime: Lifetime) -> Self {
30 Self { lifetime, data }
31 }
32
33 pub fn into_inner(self) -> (Lifetime, T) {
34 (self.lifetime, self.data)
35 }
36
37 pub fn into_dynamic(self) -> Result<DynamicManaged, Self> {
38 match DynamicManaged::new(self.data) {
39 Ok(value) => Ok(value),
40 Err(data) => Err(Managed {
41 lifetime: self.lifetime,
42 data,
43 }),
44 }
45 }
46
47 pub fn renew(mut self) -> Self {
48 self.lifetime = Lifetime::default();
49 self
50 }
51
52 pub fn lifetime(&self) -> &Lifetime {
53 &self.lifetime
54 }
55
56 pub fn read(&'_ self) -> Option<ValueReadAccess<'_, T>> {
57 self.lifetime.read(&self.data)
58 }
59
60 pub fn write(&'_ mut self) -> Option<ValueWriteAccess<'_, T>> {
61 self.lifetime.write(&mut self.data)
62 }
63
64 pub fn consume(self) -> Result<T, Self> {
65 if self.lifetime.state().is_in_use() {
66 Err(self)
67 } else {
68 Ok(self.data)
69 }
70 }
71
72 pub fn move_into_ref(self, mut target: ManagedRefMut<T>) -> Result<(), Self> {
73 *target.write().unwrap() = self.consume()?;
74 Ok(())
75 }
76
77 pub fn move_into_lazy(self, target: ManagedLazy<T>) -> Result<(), Self> {
78 *target.write().unwrap() = self.consume()?;
79 Ok(())
80 }
81
82 pub fn borrow(&self) -> Option<ManagedRef<T>> {
83 Some(ManagedRef::new(&self.data, self.lifetime.borrow()?))
84 }
85
86 pub fn borrow_mut(&mut self) -> Option<ManagedRefMut<T>> {
87 Some(ManagedRefMut::new(
88 &mut self.data,
89 self.lifetime.borrow_mut()?,
90 ))
91 }
92
93 pub fn lazy(&mut self) -> ManagedLazy<T> {
94 ManagedLazy::new(&mut self.data, self.lifetime.lazy())
95 }
96
97 pub unsafe fn lazy_immutable(&self) -> ManagedLazy<T> {
99 unsafe {
100 ManagedLazy::new_raw(&self.data as *const T as *mut T, self.lifetime.lazy()).unwrap()
101 }
102 }
103
104 pub unsafe fn map<U>(self, f: impl FnOnce(T) -> U) -> Managed<U> {
106 Managed {
107 lifetime: Default::default(),
108 data: f(self.data),
109 }
110 }
111
112 pub unsafe fn try_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Managed<U>> {
114 f(self.data).map(|data| Managed {
115 lifetime: Default::default(),
116 data,
117 })
118 }
119
120 pub unsafe fn as_ptr(&self) -> *const T {
122 &self.data as _
123 }
124
125 pub unsafe fn as_mut_ptr(&mut self) -> *mut T {
127 &mut self.data as _
128 }
129}
130
131pub struct ManagedRef<T: ?Sized> {
132 lifetime: LifetimeRef,
133 data: *const T,
134}
135
136unsafe impl<T: ?Sized> Send for ManagedRef<T> where T: Send {}
137unsafe impl<T: ?Sized> Sync for ManagedRef<T> where T: Sync {}
138
139impl<T: ?Sized> ManagedRef<T> {
140 pub fn new(data: &T, lifetime: LifetimeRef) -> Self {
141 Self {
142 lifetime,
143 data: data as *const T,
144 }
145 }
146
147 pub unsafe fn new_raw(data: *const T, lifetime: LifetimeRef) -> Option<Self> {
149 if data.is_null() {
150 None
151 } else {
152 Some(Self { lifetime, data })
153 }
154 }
155
156 pub fn make(data: &T) -> (Self, Lifetime) {
157 let result = Lifetime::default();
158 (Self::new(data, result.borrow().unwrap()), result)
159 }
160
161 pub unsafe fn make_raw(data: *const T) -> Option<(Self, Lifetime)> {
163 let result = Lifetime::default();
164 Some((
165 unsafe { Self::new_raw(data, result.borrow().unwrap()) }?,
166 result,
167 ))
168 }
169
170 pub fn into_inner(self) -> (LifetimeRef, *const T) {
171 (self.lifetime, self.data)
172 }
173
174 pub fn into_dynamic(self) -> DynamicManagedRef {
175 unsafe {
176 DynamicManagedRef::new_raw(TypeHash::of::<T>(), self.lifetime, self.data as *const u8)
177 .unwrap()
178 }
179 }
180
181 pub fn lifetime(&self) -> &LifetimeRef {
182 &self.lifetime
183 }
184
185 pub fn borrow(&self) -> Option<ManagedRef<T>> {
186 Some(ManagedRef {
187 lifetime: self.lifetime.borrow()?,
188 data: self.data,
189 })
190 }
191
192 pub unsafe fn lazy_immutable(&self) -> ManagedLazy<T> {
194 ManagedLazy {
195 lifetime: self.lifetime.lazy(),
196 data: self.data as *mut T,
197 }
198 }
199
200 pub fn read(&'_ self) -> Option<ValueReadAccess<'_, T>> {
201 unsafe { self.lifetime.read_ptr(self.data) }
202 }
203
204 pub unsafe fn map<U>(self, f: impl FnOnce(&T) -> &U) -> ManagedRef<U> {
206 unsafe {
207 let data = f(&*self.data);
208 ManagedRef {
209 lifetime: self.lifetime,
210 data: data as *const U,
211 }
212 }
213 }
214
215 pub unsafe fn try_map<U>(self, f: impl FnOnce(&T) -> Option<&U>) -> Option<ManagedRef<U>> {
217 unsafe {
218 f(&*self.data).map(|data| ManagedRef {
219 lifetime: self.lifetime,
220 data: data as *const U,
221 })
222 }
223 }
224
225 pub unsafe fn as_ptr(&self) -> Option<*const T> {
227 if self.lifetime.exists() {
228 Some(self.data)
229 } else {
230 None
231 }
232 }
233}
234
235impl<T> TryFrom<ManagedValue<T>> for ManagedRef<T> {
236 type Error = ();
237
238 fn try_from(value: ManagedValue<T>) -> Result<Self, Self::Error> {
239 match value {
240 ManagedValue::Ref(value) => Ok(value),
241 _ => Err(()),
242 }
243 }
244}
245
246pub struct ManagedRefMut<T: ?Sized> {
247 lifetime: LifetimeRefMut,
248 data: *mut T,
249}
250
251unsafe impl<T: ?Sized> Send for ManagedRefMut<T> where T: Send {}
252unsafe impl<T: ?Sized> Sync for ManagedRefMut<T> where T: Sync {}
253
254impl<T: ?Sized> ManagedRefMut<T> {
255 pub fn new(data: &mut T, lifetime: LifetimeRefMut) -> Self {
256 Self {
257 lifetime,
258 data: data as *mut T,
259 }
260 }
261
262 pub unsafe fn new_raw(data: *mut T, lifetime: LifetimeRefMut) -> Option<Self> {
264 if data.is_null() {
265 None
266 } else {
267 Some(Self { lifetime, data })
268 }
269 }
270
271 pub fn make(data: &mut T) -> (Self, Lifetime) {
272 let result = Lifetime::default();
273 (Self::new(data, result.borrow_mut().unwrap()), result)
274 }
275
276 pub unsafe fn make_raw(data: *mut T) -> Option<(Self, Lifetime)> {
278 let result = Lifetime::default();
279 Some((
280 unsafe { Self::new_raw(data, result.borrow_mut().unwrap()) }?,
281 result,
282 ))
283 }
284
285 pub fn into_inner(self) -> (LifetimeRefMut, *mut T) {
286 (self.lifetime, self.data)
287 }
288
289 pub fn into_dynamic(self) -> DynamicManagedRefMut {
290 unsafe {
291 DynamicManagedRefMut::new_raw(TypeHash::of::<T>(), self.lifetime, self.data as *mut u8)
292 .unwrap()
293 }
294 }
295
296 pub fn lifetime(&self) -> &LifetimeRefMut {
297 &self.lifetime
298 }
299
300 pub fn borrow(&self) -> Option<ManagedRef<T>> {
301 Some(ManagedRef {
302 lifetime: self.lifetime.borrow()?,
303 data: self.data,
304 })
305 }
306
307 pub fn borrow_mut(&mut self) -> Option<ManagedRefMut<T>> {
308 Some(ManagedRefMut {
309 lifetime: self.lifetime.borrow_mut()?,
310 data: self.data,
311 })
312 }
313
314 pub fn lazy(&self) -> ManagedLazy<T> {
315 ManagedLazy {
316 lifetime: self.lifetime.lazy(),
317 data: self.data,
318 }
319 }
320
321 pub fn read(&'_ self) -> Option<ValueReadAccess<'_, T>> {
322 unsafe { self.lifetime.read_ptr(self.data) }
323 }
324
325 pub fn write(&'_ mut self) -> Option<ValueWriteAccess<'_, T>> {
326 unsafe { self.lifetime.write_ptr(self.data) }
327 }
328
329 pub unsafe fn map<U>(self, f: impl FnOnce(&mut T) -> &mut U) -> ManagedRefMut<U> {
331 unsafe {
332 let data = f(&mut *self.data);
333 ManagedRefMut {
334 lifetime: self.lifetime,
335 data: data as *mut U,
336 }
337 }
338 }
339
340 pub unsafe fn try_map<U>(
342 self,
343 f: impl FnOnce(&mut T) -> Option<&mut U>,
344 ) -> Option<ManagedRefMut<U>> {
345 unsafe {
346 f(&mut *self.data).map(|data| ManagedRefMut {
347 lifetime: self.lifetime,
348 data: data as *mut U,
349 })
350 }
351 }
352
353 pub unsafe fn as_ptr(&self) -> Option<*const T> {
355 if self.lifetime.exists() {
356 Some(self.data)
357 } else {
358 None
359 }
360 }
361
362 pub unsafe fn as_mut_ptr(&mut self) -> Option<*mut T> {
364 if self.lifetime.exists() {
365 Some(self.data)
366 } else {
367 None
368 }
369 }
370}
371
372impl<T> TryFrom<ManagedValue<T>> for ManagedRefMut<T> {
373 type Error = ();
374
375 fn try_from(value: ManagedValue<T>) -> Result<Self, Self::Error> {
376 match value {
377 ManagedValue::RefMut(value) => Ok(value),
378 _ => Err(()),
379 }
380 }
381}
382
383pub struct ManagedLazy<T: ?Sized> {
384 lifetime: LifetimeLazy,
385 data: *mut T,
386}
387
388unsafe impl<T: ?Sized> Send for ManagedLazy<T> where T: Send {}
389unsafe impl<T: ?Sized> Sync for ManagedLazy<T> where T: Sync {}
390
391impl<T: ?Sized> Clone for ManagedLazy<T> {
392 fn clone(&self) -> Self {
393 Self {
394 lifetime: self.lifetime.clone(),
395 data: self.data,
396 }
397 }
398}
399
400impl<T: ?Sized> ManagedLazy<T> {
401 pub fn new(data: &mut T, lifetime: LifetimeLazy) -> Self {
402 Self {
403 lifetime,
404 data: data as *mut T,
405 }
406 }
407
408 pub unsafe fn new_raw(data: *mut T, lifetime: LifetimeLazy) -> Option<Self> {
410 if data.is_null() {
411 None
412 } else {
413 Some(Self { lifetime, data })
414 }
415 }
416
417 pub fn make(data: &mut T) -> (Self, Lifetime) {
418 let result = Lifetime::default();
419 (Self::new(data, result.lazy()), result)
420 }
421
422 pub unsafe fn make_raw(data: *mut T) -> Option<(Self, Lifetime)> {
424 let result = Lifetime::default();
425 Some((unsafe { Self::new_raw(data, result.lazy()) }?, result))
426 }
427
428 pub fn into_inner(self) -> (LifetimeLazy, *mut T) {
429 (self.lifetime, self.data)
430 }
431
432 pub fn into_dynamic(self) -> DynamicManagedLazy {
433 unsafe {
434 DynamicManagedLazy::new_raw(TypeHash::of::<T>(), self.lifetime, self.data as *mut u8)
435 .unwrap()
436 }
437 }
438
439 pub fn lifetime(&self) -> &LifetimeLazy {
440 &self.lifetime
441 }
442
443 pub fn borrow(&self) -> Option<ManagedRef<T>> {
444 Some(ManagedRef {
445 lifetime: self.lifetime.borrow()?,
446 data: self.data,
447 })
448 }
449
450 pub fn borrow_mut(&mut self) -> Option<ManagedRefMut<T>> {
451 Some(ManagedRefMut {
452 lifetime: self.lifetime.borrow_mut()?,
453 data: self.data,
454 })
455 }
456
457 pub fn read(&'_ self) -> Option<ValueReadAccess<'_, T>> {
458 unsafe { self.lifetime.read_ptr(self.data) }
459 }
460
461 pub fn write(&'_ self) -> Option<ValueWriteAccess<'_, T>> {
462 unsafe { self.lifetime.write_ptr(self.data) }
463 }
464
465 pub unsafe fn map<U>(self, f: impl FnOnce(&mut T) -> &mut U) -> ManagedLazy<U> {
467 unsafe {
468 let data = f(&mut *self.data);
469 ManagedLazy {
470 lifetime: self.lifetime,
471 data: data as *mut U,
472 }
473 }
474 }
475
476 pub unsafe fn try_map<U>(
478 self,
479 f: impl FnOnce(&mut T) -> Option<&mut U>,
480 ) -> Option<ManagedLazy<U>> {
481 unsafe {
482 f(&mut *self.data).map(|data| ManagedLazy {
483 lifetime: self.lifetime,
484 data: data as *mut U,
485 })
486 }
487 }
488
489 pub unsafe fn as_ptr(&self) -> Option<*const T> {
491 if self.lifetime.exists() {
492 Some(self.data)
493 } else {
494 None
495 }
496 }
497
498 pub unsafe fn as_mut_ptr(&self) -> Option<*mut T> {
500 if self.lifetime.exists() {
501 Some(self.data)
502 } else {
503 None
504 }
505 }
506}
507
508impl<T> TryFrom<ManagedValue<T>> for ManagedLazy<T> {
509 type Error = ();
510
511 fn try_from(value: ManagedValue<T>) -> Result<Self, Self::Error> {
512 match value {
513 ManagedValue::Lazy(value) => Ok(value),
514 _ => Err(()),
515 }
516 }
517}
518
519pub struct DynamicManaged {
520 type_hash: TypeHash,
521 lifetime: Lifetime,
522 memory: *mut u8,
523 layout: Layout,
524 finalizer: unsafe fn(*mut ()),
525 drop: bool,
526}
527
528unsafe impl Send for DynamicManaged {}
529unsafe impl Sync for DynamicManaged {}
530
531impl Drop for DynamicManaged {
532 fn drop(&mut self) {
533 if self.drop {
534 unsafe {
535 if self.memory.is_null() {
536 return;
537 }
538 let data_pointer = self.memory.cast::<()>();
539 (self.finalizer)(data_pointer);
540 non_zero_dealloc(self.memory, self.layout);
541 self.memory = std::ptr::null_mut();
542 }
543 }
544 }
545}
546
547impl DynamicManaged {
548 pub fn new<T: Finalize>(data: T) -> Result<Self, T> {
549 let layout = Layout::new::<T>().pad_to_align();
550 unsafe {
551 let memory = non_zero_alloc(layout);
552 if memory.is_null() {
553 Err(data)
554 } else {
555 memory.cast::<T>().write(data);
556 Ok(Self {
557 type_hash: TypeHash::of::<T>(),
558 lifetime: Default::default(),
559 memory,
560 layout,
561 finalizer: T::finalize_raw,
562 drop: true,
563 })
564 }
565 }
566 }
567
568 pub fn new_raw(
569 type_hash: TypeHash,
570 lifetime: Lifetime,
571 memory: *mut u8,
572 layout: Layout,
573 finalizer: unsafe fn(*mut ()),
574 ) -> Option<Self> {
575 if memory.is_null() {
576 None
577 } else {
578 Some(Self {
579 type_hash,
580 lifetime,
581 memory,
582 layout,
583 finalizer,
584 drop: true,
585 })
586 }
587 }
588
589 pub fn new_uninitialized(
590 type_hash: TypeHash,
591 layout: Layout,
592 finalizer: unsafe fn(*mut ()),
593 ) -> Self {
594 let layout = layout.pad_to_align();
595 let memory = unsafe { non_zero_alloc(layout) };
596 Self {
597 type_hash,
598 lifetime: Default::default(),
599 memory,
600 layout,
601 finalizer,
602 drop: true,
603 }
604 }
605
606 pub unsafe fn from_bytes(
608 type_hash: TypeHash,
609 lifetime: Lifetime,
610 bytes: Vec<u8>,
611 layout: Layout,
612 finalizer: unsafe fn(*mut ()),
613 ) -> Self {
614 let layout = layout.pad_to_align();
615 let memory = unsafe { non_zero_alloc(layout) };
616 unsafe { memory.copy_from(bytes.as_ptr(), bytes.len()) };
617 Self {
618 type_hash,
619 lifetime,
620 memory,
621 layout,
622 finalizer,
623 drop: true,
624 }
625 }
626
627 #[allow(clippy::type_complexity)]
628 pub fn into_inner(mut self) -> (TypeHash, Lifetime, *mut u8, Layout, unsafe fn(*mut ())) {
629 self.drop = false;
630 (
631 self.type_hash,
632 std::mem::take(&mut self.lifetime),
633 self.memory,
634 self.layout,
635 self.finalizer,
636 )
637 }
638
639 pub fn into_typed<T>(self) -> Result<Managed<T>, Self> {
640 Ok(Managed::new(self.consume()?))
641 }
642
643 pub fn renew(mut self) -> Self {
644 self.lifetime = Lifetime::default();
645 self
646 }
647
648 pub fn type_hash(&self) -> &TypeHash {
649 &self.type_hash
650 }
651
652 pub fn lifetime(&self) -> &Lifetime {
653 &self.lifetime
654 }
655
656 pub fn layout(&self) -> &Layout {
657 &self.layout
658 }
659
660 pub fn finalizer(&self) -> unsafe fn(*mut ()) {
661 self.finalizer
662 }
663
664 pub unsafe fn memory(&self) -> &[u8] {
666 unsafe { std::slice::from_raw_parts(self.memory, self.layout.size()) }
667 }
668
669 pub unsafe fn memory_mut(&mut self) -> &mut [u8] {
671 unsafe { std::slice::from_raw_parts_mut(self.memory, self.layout.size()) }
672 }
673
674 pub fn is<T>(&self) -> bool {
675 self.type_hash == TypeHash::of::<T>()
676 }
677
678 pub fn read<T>(&'_ self) -> Option<ValueReadAccess<'_, T>> {
679 if self.type_hash == TypeHash::of::<T>() {
680 unsafe { self.lifetime.read_ptr(self.memory.cast::<T>()) }
681 } else {
682 None
683 }
684 }
685
686 pub fn write<T>(&'_ mut self) -> Option<ValueWriteAccess<'_, T>> {
687 if self.type_hash == TypeHash::of::<T>() {
688 unsafe { self.lifetime.write_ptr(self.memory.cast::<T>()) }
689 } else {
690 None
691 }
692 }
693
694 pub fn consume<T>(mut self) -> Result<T, Self> {
695 if self.type_hash == TypeHash::of::<T>() && !self.lifetime.state().is_in_use() {
696 if self.memory.is_null() {
697 return Err(self);
698 }
699 self.drop = false;
700 let mut result = MaybeUninit::<T>::uninit();
701 unsafe {
702 result.as_mut_ptr().copy_from(self.memory.cast::<T>(), 1);
703 non_zero_dealloc(self.memory, self.layout);
704 self.memory = std::ptr::null_mut();
705 Ok(result.assume_init())
706 }
707 } else {
708 Err(self)
709 }
710 }
711
712 pub fn move_into_ref(self, target: DynamicManagedRefMut) -> Result<(), Self> {
713 if self.type_hash == target.type_hash && self.memory != target.data {
714 if self.memory.is_null() {
715 return Err(self);
716 }
717 let (_, _, memory, layout, _) = self.into_inner();
718 unsafe {
719 target.data.copy_from(memory, layout.size());
720 non_zero_dealloc(memory, layout);
721 }
722 Ok(())
723 } else {
724 Err(self)
725 }
726 }
727
728 pub fn move_into_lazy(self, target: DynamicManagedLazy) -> Result<(), Self> {
729 if self.type_hash == target.type_hash && self.memory != target.data {
730 if self.memory.is_null() {
731 return Err(self);
732 }
733 let (_, _, memory, layout, _) = self.into_inner();
734 unsafe {
735 target.data.copy_from(memory, layout.size());
736 non_zero_dealloc(memory, layout);
737 }
738 Ok(())
739 } else {
740 Err(self)
741 }
742 }
743
744 pub fn borrow(&self) -> Option<DynamicManagedRef> {
745 unsafe { DynamicManagedRef::new_raw(self.type_hash, self.lifetime.borrow()?, self.memory) }
746 }
747
748 pub fn borrow_mut(&mut self) -> Option<DynamicManagedRefMut> {
749 unsafe {
750 DynamicManagedRefMut::new_raw(self.type_hash, self.lifetime.borrow_mut()?, self.memory)
751 }
752 }
753
754 pub fn lazy(&self) -> DynamicManagedLazy {
755 unsafe {
756 DynamicManagedLazy::new_raw(self.type_hash, self.lifetime.lazy(), self.memory).unwrap()
757 }
758 }
759
760 pub unsafe fn map<T, U: Finalize>(self, f: impl FnOnce(T) -> U) -> Option<Self> {
762 let data = self.consume::<T>().ok()?;
763 let data = f(data);
764 Self::new(data).ok()
765 }
766
767 pub unsafe fn try_map<T, U: Finalize>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Self> {
769 let data = self.consume::<T>().ok()?;
770 let data = f(data)?;
771 Self::new(data).ok()
772 }
773
774 pub unsafe fn as_ptr<T>(&self) -> Option<*const T> {
776 if self.type_hash == TypeHash::of::<T>() && !self.lifetime.state().is_in_use() {
777 Some(self.memory.cast::<T>())
778 } else {
779 None
780 }
781 }
782
783 pub unsafe fn as_mut_ptr<T>(&mut self) -> Option<*mut T> {
785 if self.type_hash == TypeHash::of::<T>() && !self.lifetime.state().is_in_use() {
786 Some(self.memory.cast::<T>())
787 } else {
788 None
789 }
790 }
791
792 pub unsafe fn as_ptr_raw(&self) -> *const u8 {
794 self.memory
795 }
796
797 pub unsafe fn as_mut_ptr_raw(&mut self) -> *mut u8 {
799 self.memory
800 }
801}
802
803impl TryFrom<DynamicManagedValue> for DynamicManaged {
804 type Error = ();
805
806 fn try_from(value: DynamicManagedValue) -> Result<Self, Self::Error> {
807 match value {
808 DynamicManagedValue::Owned(value) => Ok(value),
809 _ => Err(()),
810 }
811 }
812}
813
814pub struct DynamicManagedRef {
815 type_hash: TypeHash,
816 lifetime: LifetimeRef,
817 data: *const u8,
818}
819
820unsafe impl Send for DynamicManagedRef {}
821unsafe impl Sync for DynamicManagedRef {}
822
823impl DynamicManagedRef {
824 pub fn new<T: ?Sized>(data: &T, lifetime: LifetimeRef) -> Self {
825 Self {
826 type_hash: TypeHash::of::<T>(),
827 lifetime,
828 data: data as *const T as *const u8,
829 }
830 }
831
832 pub unsafe fn new_raw(
834 type_hash: TypeHash,
835 lifetime: LifetimeRef,
836 data: *const u8,
837 ) -> Option<Self> {
838 if data.is_null() {
839 None
840 } else {
841 Some(Self {
842 type_hash,
843 lifetime,
844 data,
845 })
846 }
847 }
848
849 pub fn make<T: ?Sized>(data: &T) -> (Self, Lifetime) {
850 let result = Lifetime::default();
851 (Self::new(data, result.borrow().unwrap()), result)
852 }
853
854 pub fn into_inner(self) -> (TypeHash, LifetimeRef, *const u8) {
855 (self.type_hash, self.lifetime, self.data)
856 }
857
858 pub fn into_typed<T>(self) -> Result<ManagedRef<T>, Self> {
859 if self.type_hash == TypeHash::of::<T>() {
860 unsafe { Ok(ManagedRef::new_raw(self.data.cast::<T>(), self.lifetime).unwrap()) }
861 } else {
862 Err(self)
863 }
864 }
865
866 pub fn type_hash(&self) -> &TypeHash {
867 &self.type_hash
868 }
869
870 pub fn lifetime(&self) -> &LifetimeRef {
871 &self.lifetime
872 }
873
874 pub fn borrow(&self) -> Option<DynamicManagedRef> {
875 Some(DynamicManagedRef {
876 type_hash: self.type_hash,
877 lifetime: self.lifetime.borrow()?,
878 data: self.data,
879 })
880 }
881
882 pub unsafe fn lazy_immutable(&self) -> DynamicManagedLazy {
884 DynamicManagedLazy {
885 type_hash: self.type_hash,
886 lifetime: self.lifetime.lazy(),
887 data: self.data as *mut u8,
888 }
889 }
890
891 pub fn is<T>(&self) -> bool {
892 self.type_hash == TypeHash::of::<T>()
893 }
894
895 pub fn read<T>(&'_ self) -> Option<ValueReadAccess<'_, T>> {
896 if self.type_hash == TypeHash::of::<T>() {
897 unsafe { self.lifetime.read_ptr(self.data.cast::<T>()) }
898 } else {
899 None
900 }
901 }
902
903 pub unsafe fn map<T, U>(self, f: impl FnOnce(&T) -> &U) -> Option<Self> {
905 if self.type_hash == TypeHash::of::<T>() {
906 unsafe {
907 let data = f(&*self.data.cast::<T>());
908 Some(Self {
909 type_hash: TypeHash::of::<U>(),
910 lifetime: self.lifetime,
911 data: data as *const U as *const u8,
912 })
913 }
914 } else {
915 None
916 }
917 }
918
919 pub unsafe fn try_map<T, U>(self, f: impl FnOnce(&T) -> Option<&U>) -> Option<Self> {
921 if self.type_hash == TypeHash::of::<T>() {
922 unsafe {
923 let data = f(&*self.data.cast::<T>())?;
924 Some(Self {
925 type_hash: TypeHash::of::<U>(),
926 lifetime: self.lifetime,
927 data: data as *const U as *const u8,
928 })
929 }
930 } else {
931 None
932 }
933 }
934
935 pub unsafe fn as_ptr<T>(&self) -> Option<*const T> {
937 if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
938 Some(self.data.cast::<T>())
939 } else {
940 None
941 }
942 }
943
944 pub unsafe fn as_ptr_raw(&self) -> Option<*const u8> {
946 if self.lifetime.exists() {
947 Some(self.data)
948 } else {
949 None
950 }
951 }
952}
953
954impl TryFrom<DynamicManagedValue> for DynamicManagedRef {
955 type Error = ();
956
957 fn try_from(value: DynamicManagedValue) -> Result<Self, Self::Error> {
958 match value {
959 DynamicManagedValue::Ref(value) => Ok(value),
960 _ => Err(()),
961 }
962 }
963}
964
965pub struct DynamicManagedRefMut {
966 type_hash: TypeHash,
967 lifetime: LifetimeRefMut,
968 data: *mut u8,
969}
970
971unsafe impl Send for DynamicManagedRefMut {}
972unsafe impl Sync for DynamicManagedRefMut {}
973
974impl DynamicManagedRefMut {
975 pub fn new<T: ?Sized>(data: &mut T, lifetime: LifetimeRefMut) -> Self {
976 Self {
977 type_hash: TypeHash::of::<T>(),
978 lifetime,
979 data: data as *mut T as *mut u8,
980 }
981 }
982
983 pub unsafe fn new_raw(
985 type_hash: TypeHash,
986 lifetime: LifetimeRefMut,
987 data: *mut u8,
988 ) -> Option<Self> {
989 if data.is_null() {
990 None
991 } else {
992 Some(Self {
993 type_hash,
994 lifetime,
995 data,
996 })
997 }
998 }
999
1000 pub fn make<T: ?Sized>(data: &mut T) -> (Self, Lifetime) {
1001 let result = Lifetime::default();
1002 (Self::new(data, result.borrow_mut().unwrap()), result)
1003 }
1004
1005 pub fn into_inner(self) -> (TypeHash, LifetimeRefMut, *mut u8) {
1006 (self.type_hash, self.lifetime, self.data)
1007 }
1008
1009 pub fn into_typed<T>(self) -> Result<ManagedRefMut<T>, Self> {
1010 if self.type_hash == TypeHash::of::<T>() {
1011 unsafe { Ok(ManagedRefMut::new_raw(self.data.cast::<T>(), self.lifetime).unwrap()) }
1012 } else {
1013 Err(self)
1014 }
1015 }
1016
1017 pub fn type_hash(&self) -> &TypeHash {
1018 &self.type_hash
1019 }
1020
1021 pub fn lifetime(&self) -> &LifetimeRefMut {
1022 &self.lifetime
1023 }
1024
1025 pub fn borrow(&self) -> Option<DynamicManagedRef> {
1026 Some(DynamicManagedRef {
1027 type_hash: self.type_hash,
1028 lifetime: self.lifetime.borrow()?,
1029 data: self.data,
1030 })
1031 }
1032
1033 pub fn borrow_mut(&mut self) -> Option<DynamicManagedRefMut> {
1034 Some(DynamicManagedRefMut {
1035 type_hash: self.type_hash,
1036 lifetime: self.lifetime.borrow_mut()?,
1037 data: self.data,
1038 })
1039 }
1040
1041 pub fn lazy(&self) -> DynamicManagedLazy {
1042 DynamicManagedLazy {
1043 type_hash: self.type_hash,
1044 lifetime: self.lifetime.lazy(),
1045 data: self.data,
1046 }
1047 }
1048
1049 pub fn is<T>(&self) -> bool {
1050 self.type_hash == TypeHash::of::<T>()
1051 }
1052
1053 pub fn read<T>(&'_ self) -> Option<ValueReadAccess<'_, T>> {
1054 if self.type_hash == TypeHash::of::<T>() {
1055 unsafe { self.lifetime.read_ptr(self.data.cast::<T>()) }
1056 } else {
1057 None
1058 }
1059 }
1060
1061 pub fn write<T>(&'_ mut self) -> Option<ValueWriteAccess<'_, T>> {
1062 if self.type_hash == TypeHash::of::<T>() {
1063 unsafe { self.lifetime.write_ptr(self.data.cast::<T>()) }
1064 } else {
1065 None
1066 }
1067 }
1068
1069 pub unsafe fn map<T, U>(self, f: impl FnOnce(&mut T) -> &mut U) -> Option<Self> {
1071 if self.type_hash == TypeHash::of::<T>() {
1072 unsafe {
1073 let data = f(&mut *self.data.cast::<T>());
1074 Some(Self {
1075 type_hash: TypeHash::of::<U>(),
1076 lifetime: self.lifetime,
1077 data: data as *mut U as *mut u8,
1078 })
1079 }
1080 } else {
1081 None
1082 }
1083 }
1084
1085 pub unsafe fn try_map<T, U>(self, f: impl FnOnce(&mut T) -> Option<&mut U>) -> Option<Self> {
1087 if self.type_hash == TypeHash::of::<T>() {
1088 unsafe {
1089 let data = f(&mut *self.data.cast::<T>())?;
1090 Some(Self {
1091 type_hash: TypeHash::of::<U>(),
1092 lifetime: self.lifetime,
1093 data: data as *mut U as *mut u8,
1094 })
1095 }
1096 } else {
1097 None
1098 }
1099 }
1100
1101 pub unsafe fn as_ptr<T>(&self) -> Option<*const T> {
1103 if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1104 Some(self.data.cast::<T>())
1105 } else {
1106 None
1107 }
1108 }
1109
1110 pub unsafe fn as_mut_ptr<T>(&mut self) -> Option<*mut T> {
1112 if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1113 Some(self.data.cast::<T>())
1114 } else {
1115 None
1116 }
1117 }
1118
1119 pub unsafe fn as_ptr_raw(&self) -> Option<*const u8> {
1121 if self.lifetime.exists() {
1122 Some(self.data)
1123 } else {
1124 None
1125 }
1126 }
1127
1128 pub unsafe fn as_mut_ptr_raw(&mut self) -> Option<*mut u8> {
1130 if self.lifetime.exists() {
1131 Some(self.data)
1132 } else {
1133 None
1134 }
1135 }
1136}
1137
1138impl TryFrom<DynamicManagedValue> for DynamicManagedRefMut {
1139 type Error = ();
1140
1141 fn try_from(value: DynamicManagedValue) -> Result<Self, Self::Error> {
1142 match value {
1143 DynamicManagedValue::RefMut(value) => Ok(value),
1144 _ => Err(()),
1145 }
1146 }
1147}
1148
1149pub struct DynamicManagedLazy {
1150 type_hash: TypeHash,
1151 lifetime: LifetimeLazy,
1152 data: *mut u8,
1153}
1154
1155unsafe impl Send for DynamicManagedLazy {}
1156unsafe impl Sync for DynamicManagedLazy {}
1157
1158impl Clone for DynamicManagedLazy {
1159 fn clone(&self) -> Self {
1160 Self {
1161 type_hash: self.type_hash,
1162 lifetime: self.lifetime.clone(),
1163 data: self.data,
1164 }
1165 }
1166}
1167
1168impl DynamicManagedLazy {
1169 pub fn new<T: ?Sized>(data: &mut T, lifetime: LifetimeLazy) -> Self {
1170 Self {
1171 type_hash: TypeHash::of::<T>(),
1172 lifetime,
1173 data: data as *mut T as *mut u8,
1174 }
1175 }
1176
1177 pub unsafe fn new_raw(
1179 type_hash: TypeHash,
1180 lifetime: LifetimeLazy,
1181 data: *mut u8,
1182 ) -> Option<Self> {
1183 if data.is_null() {
1184 None
1185 } else {
1186 Some(Self {
1187 type_hash,
1188 lifetime,
1189 data,
1190 })
1191 }
1192 }
1193
1194 pub fn make<T: ?Sized>(data: &mut T) -> (Self, Lifetime) {
1195 let result = Lifetime::default();
1196 (Self::new(data, result.lazy()), result)
1197 }
1198
1199 pub fn into_inner(self) -> (TypeHash, LifetimeLazy, *mut u8) {
1200 (self.type_hash, self.lifetime, self.data)
1201 }
1202
1203 pub fn into_typed<T>(self) -> Result<ManagedLazy<T>, Self> {
1204 if self.type_hash == TypeHash::of::<T>() {
1205 unsafe { Ok(ManagedLazy::new_raw(self.data.cast::<T>(), self.lifetime).unwrap()) }
1206 } else {
1207 Err(self)
1208 }
1209 }
1210
1211 pub fn type_hash(&self) -> &TypeHash {
1212 &self.type_hash
1213 }
1214
1215 pub fn lifetime(&self) -> &LifetimeLazy {
1216 &self.lifetime
1217 }
1218
1219 pub fn is<T>(&self) -> bool {
1220 self.type_hash == TypeHash::of::<T>()
1221 }
1222
1223 pub fn read<T>(&'_ self) -> Option<ValueReadAccess<'_, T>> {
1224 if self.type_hash == TypeHash::of::<T>() {
1225 unsafe { self.lifetime.read_ptr(self.data.cast::<T>()) }
1226 } else {
1227 None
1228 }
1229 }
1230
1231 pub fn write<T>(&'_ self) -> Option<ValueWriteAccess<'_, T>> {
1232 if self.type_hash == TypeHash::of::<T>() {
1233 unsafe { self.lifetime.write_ptr(self.data.cast::<T>()) }
1234 } else {
1235 None
1236 }
1237 }
1238
1239 pub fn borrow(&self) -> Option<DynamicManagedRef> {
1240 Some(DynamicManagedRef {
1241 type_hash: self.type_hash,
1242 lifetime: self.lifetime.borrow()?,
1243 data: self.data,
1244 })
1245 }
1246
1247 pub fn borrow_mut(&mut self) -> Option<DynamicManagedRefMut> {
1248 Some(DynamicManagedRefMut {
1249 type_hash: self.type_hash,
1250 lifetime: self.lifetime.borrow_mut()?,
1251 data: self.data,
1252 })
1253 }
1254
1255 pub unsafe fn map<T, U>(self, f: impl FnOnce(&mut T) -> &mut U) -> Option<Self> {
1257 if self.type_hash == TypeHash::of::<T>() {
1258 unsafe {
1259 let data = f(&mut *self.data.cast::<T>());
1260 Some(Self {
1261 type_hash: TypeHash::of::<U>(),
1262 lifetime: self.lifetime,
1263 data: data as *mut U as *mut u8,
1264 })
1265 }
1266 } else {
1267 None
1268 }
1269 }
1270
1271 pub unsafe fn try_map<T, U>(self, f: impl FnOnce(&mut T) -> Option<&mut U>) -> Option<Self> {
1273 if self.type_hash == TypeHash::of::<T>() {
1274 unsafe {
1275 let data = f(&mut *self.data.cast::<T>())?;
1276 Some(Self {
1277 type_hash: TypeHash::of::<U>(),
1278 lifetime: self.lifetime,
1279 data: data as *mut U as *mut u8,
1280 })
1281 }
1282 } else {
1283 None
1284 }
1285 }
1286
1287 pub unsafe fn as_ptr<T>(&self) -> Option<*const T> {
1289 if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1290 Some(self.data.cast::<T>())
1291 } else {
1292 None
1293 }
1294 }
1295
1296 pub unsafe fn as_mut_ptr<T>(&self) -> Option<*mut T> {
1298 if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1299 Some(self.data.cast::<T>())
1300 } else {
1301 None
1302 }
1303 }
1304
1305 pub unsafe fn as_ptr_raw(&self) -> Option<*const u8> {
1307 if self.lifetime.exists() {
1308 Some(self.data)
1309 } else {
1310 None
1311 }
1312 }
1313
1314 pub unsafe fn as_mut_ptr_raw(&mut self) -> Option<*mut u8> {
1316 if self.lifetime.exists() {
1317 Some(self.data)
1318 } else {
1319 None
1320 }
1321 }
1322}
1323
1324impl TryFrom<DynamicManagedValue> for DynamicManagedLazy {
1325 type Error = ();
1326
1327 fn try_from(value: DynamicManagedValue) -> Result<Self, Self::Error> {
1328 match value {
1329 DynamicManagedValue::Lazy(value) => Ok(value),
1330 _ => Err(()),
1331 }
1332 }
1333}
1334
1335#[cfg(test)]
1336mod tests {
1337 use super::*;
1338 use std::any::Any;
1339
1340 fn is_async<T: Send + Sync + ?Sized>() {}
1341
1342 #[test]
1343 fn test_managed() {
1344 is_async::<Managed<()>>();
1345 is_async::<ManagedRef<()>>();
1346 is_async::<ManagedRefMut<()>>();
1347 is_async::<ManagedLazy<()>>();
1348 is_async::<ManagedValue<()>>();
1349
1350 let mut value = Managed::new(42);
1351 let mut value_ref = value.borrow_mut().unwrap();
1352 assert!(value_ref.write().is_some());
1353 let mut value_ref2 = value_ref.borrow_mut().unwrap();
1354 assert!(value_ref.write().is_some());
1355 assert!(value_ref2.write().is_some());
1356 drop(value_ref);
1357 let value_ref = value.borrow().unwrap();
1358 assert!(value.borrow().is_some());
1359 assert!(value.borrow_mut().is_none());
1360 drop(value_ref);
1361 assert!(value.borrow().is_some());
1362 assert!(value.borrow_mut().is_some());
1363 *value.write().unwrap() = 40;
1364 assert_eq!(*value.read().unwrap(), 40);
1365 *value.borrow_mut().unwrap().write().unwrap() = 2;
1366 assert_eq!(*value.read().unwrap(), 2);
1367 let value_ref = value.borrow().unwrap();
1368 let value_ref2 = value_ref.borrow().unwrap();
1369 drop(value_ref);
1370 assert!(value_ref2.read().is_some());
1371 let value_ref = value.borrow().unwrap();
1372 let value_lazy = value.lazy();
1373 assert_eq!(*value_lazy.read().unwrap(), 2);
1374 *value_lazy.write().unwrap() = 42;
1375 assert_eq!(*value_lazy.read().unwrap(), 42);
1376 drop(value);
1377 assert!(value_ref.read().is_none());
1378 assert!(value_ref2.read().is_none());
1379 assert!(value_lazy.read().is_none());
1380 }
1381
1382 #[test]
1383 fn test_dynamic_managed() {
1384 is_async::<DynamicManaged>();
1385 is_async::<DynamicManagedRef>();
1386 is_async::<DynamicManagedRefMut>();
1387 is_async::<DynamicManagedLazy>();
1388 is_async::<DynamicManagedValue>();
1389
1390 let mut value = DynamicManaged::new(42).unwrap();
1391 let mut value_ref = value.borrow_mut().unwrap();
1392 assert!(value_ref.write::<i32>().is_some());
1393 let mut value_ref2 = value_ref.borrow_mut().unwrap();
1394 assert!(value_ref.write::<i32>().is_some());
1395 assert!(value_ref2.write::<i32>().is_some());
1396 drop(value_ref);
1397 let value_ref = value.borrow().unwrap();
1398 assert!(value.borrow().is_some());
1399 assert!(value.borrow_mut().is_none());
1400 drop(value_ref);
1401 assert!(value.borrow().is_some());
1402 assert!(value.borrow_mut().is_some());
1403 *value.write::<i32>().unwrap() = 40;
1404 assert_eq!(*value.read::<i32>().unwrap(), 40);
1405 *value.borrow_mut().unwrap().write::<i32>().unwrap() = 2;
1406 assert_eq!(*value.read::<i32>().unwrap(), 2);
1407 let value_ref = value.borrow().unwrap();
1408 let value_ref2 = value_ref.borrow().unwrap();
1409 drop(value_ref);
1410 assert!(value_ref2.read::<i32>().is_some());
1411 let value_ref = value.borrow().unwrap();
1412 let value_lazy = value.lazy();
1413 assert_eq!(*value_lazy.read::<i32>().unwrap(), 2);
1414 *value_lazy.write::<i32>().unwrap() = 42;
1415 assert_eq!(*value_lazy.read::<i32>().unwrap(), 42);
1416 drop(value);
1417 assert!(value_ref.read::<i32>().is_none());
1418 assert!(value_ref2.read::<i32>().is_none());
1419 assert!(value_lazy.read::<i32>().is_none());
1420 let value = DynamicManaged::new("hello".to_owned()).unwrap();
1421 let value = value.consume::<String>().ok().unwrap();
1422 assert_eq!(value.as_str(), "hello");
1423 }
1424
1425 #[test]
1426 fn test_conversion() {
1427 let value = Managed::new(42);
1428 assert_eq!(*value.read().unwrap(), 42);
1429 let value = value.into_dynamic().ok().unwrap();
1430 assert_eq!(*value.read::<i32>().unwrap(), 42);
1431 let mut value = value.into_typed::<i32>().ok().unwrap();
1432 assert_eq!(*value.read().unwrap(), 42);
1433
1434 let value_ref = value.borrow().unwrap();
1435 assert_eq!(*value.read().unwrap(), 42);
1436 let value_ref = value_ref.into_dynamic();
1437 assert_eq!(*value_ref.read::<i32>().unwrap(), 42);
1438 let value_ref = value_ref.into_typed::<i32>().ok().unwrap();
1439 assert_eq!(*value_ref.read().unwrap(), 42);
1440 drop(value_ref);
1441
1442 let value_ref_mut = value.borrow_mut().unwrap();
1443 assert_eq!(*value.read().unwrap(), 42);
1444 let value_ref_mut = value_ref_mut.into_dynamic();
1445 assert_eq!(*value_ref_mut.read::<i32>().unwrap(), 42);
1446 let value_ref_mut = value_ref_mut.into_typed::<i32>().ok().unwrap();
1447 assert_eq!(*value_ref_mut.read().unwrap(), 42);
1448
1449 let value_lazy = value.lazy();
1450 assert_eq!(*value.read().unwrap(), 42);
1451 let value_lazy = value_lazy.into_dynamic();
1452 assert_eq!(*value_lazy.read::<i32>().unwrap(), 42);
1453 let value_lazy = value_lazy.into_typed::<i32>().ok().unwrap();
1454 assert_eq!(*value_lazy.read().unwrap(), 42);
1455 }
1456
1457 #[test]
1458 fn test_unsized() {
1459 let lifetime = Lifetime::default();
1460 let mut data = 42usize;
1461 {
1462 let foo = ManagedRef::<dyn Any>::new(&data, lifetime.borrow().unwrap());
1463 assert_eq!(
1464 *foo.read().unwrap().downcast_ref::<usize>().unwrap(),
1465 42usize
1466 );
1467 }
1468 {
1469 let mut foo = ManagedRefMut::<dyn Any>::new(&mut data, lifetime.borrow_mut().unwrap());
1470 *foo.write().unwrap().downcast_mut::<usize>().unwrap() = 100;
1471 }
1472 {
1473 let foo = ManagedLazy::<dyn Any>::new(&mut data, lifetime.lazy());
1474 assert_eq!(
1475 *foo.read().unwrap().downcast_ref::<usize>().unwrap(),
1476 100usize
1477 );
1478 }
1479
1480 let lifetime = Lifetime::default();
1481 let mut data = [0, 1, 2, 3];
1482 {
1483 let foo = ManagedRef::<[i32]>::new(&data, lifetime.borrow().unwrap());
1484 assert_eq!(*foo.read().unwrap(), [0, 1, 2, 3]);
1485 }
1486 {
1487 let mut foo = ManagedRefMut::<[i32]>::new(&mut data, lifetime.borrow_mut().unwrap());
1488 foo.write().unwrap().sort_by(|a, b| a.cmp(b).reverse());
1489 }
1490 {
1491 let foo = ManagedLazy::<[i32]>::new(&mut data, lifetime.lazy());
1492 assert_eq!(*foo.read().unwrap(), [3, 2, 1, 0]);
1493 }
1494 }
1495
1496 #[test]
1497 fn test_moves() {
1498 let mut value = Managed::new(42);
1499 assert_eq!(*value.read().unwrap(), 42);
1500 {
1501 let value_ref = value.borrow_mut().unwrap();
1502 Managed::new(1).move_into_ref(value_ref).ok().unwrap();
1503 assert_eq!(*value.read().unwrap(), 1);
1504 }
1505 {
1506 let value_lazy = value.lazy();
1507 Managed::new(2).move_into_lazy(value_lazy).ok().unwrap();
1508 assert_eq!(*value.read().unwrap(), 2);
1509 }
1510
1511 let mut value = DynamicManaged::new(42).unwrap();
1512 assert_eq!(*value.read::<i32>().unwrap(), 42);
1513 {
1514 let value_ref = value.borrow_mut().unwrap();
1515 DynamicManaged::new(1)
1516 .unwrap()
1517 .move_into_ref(value_ref)
1518 .ok()
1519 .unwrap();
1520 assert_eq!(*value.read::<i32>().unwrap(), 1);
1521 }
1522 {
1523 let value_lazy = value.lazy();
1524 DynamicManaged::new(2)
1525 .unwrap()
1526 .move_into_lazy(value_lazy)
1527 .ok()
1528 .unwrap();
1529 assert_eq!(*value.read::<i32>().unwrap(), 2);
1530 }
1531 }
1532
1533 #[test]
1534 fn test_move_invalidation() {
1535 let value = Managed::new(42);
1536 let value_ref = value.borrow().unwrap();
1537 assert_eq!(value.lifetime().tag(), value_ref.lifetime().tag());
1538 assert!(value_ref.lifetime().exists());
1539 let value = Box::new(value);
1540 assert_ne!(value.lifetime().tag(), value_ref.lifetime().tag());
1541 assert!(!value_ref.lifetime().exists());
1542 let value = *value;
1543 assert_ne!(value.lifetime().tag(), value_ref.lifetime().tag());
1544 assert!(!value_ref.lifetime().exists());
1545 }
1546}