loaned/take.rs
1use crate::*;
2
3/// Takes the value from a [`Loaned`] or [`LoanedMut`], statically ensuring that
4/// `'t` is expired.
5///
6/// # Example
7/// ```
8/// use loaned::{take, LoanedMut};
9/// let (borrow, loaned) = LoanedMut::loan(Box::new(123));
10/// *borrow = 456;
11/// assert_eq!(take!(loaned), Box::new(456));
12/// ```
13#[macro_export]
14macro_rules! take {
15 ($loaned:expr) => {{
16 let mut loaned = ();
17 unsafe { $crate::__take($loaned, &mut loaned) }
18 }};
19}
20
21/// Drops the value from a [`Loaned`] or [`LoanedMut`], statically ensuring that
22/// `'t` is expired.
23///
24/// # Example
25/// ```
26/// use loaned::{drop, LoanedMut};
27/// let (borrow, loaned) = LoanedMut::loan(Box::new(123));
28/// *borrow *= 2;
29/// assert_eq!(*borrow, 246);
30/// drop!(loaned); // drops the box
31/// ```
32#[macro_export]
33macro_rules! drop {
34 ($loaned:expr) => {{
35 let loaned_value;
36 let mut loaned = ();
37 loaned_value = unsafe { $crate::__take($loaned, &mut loaned) };
38 let _ = loaned_value;
39 }};
40}
41
42#[doc(hidden)]
43pub unsafe fn __take<'t, T: 't, L: Placeable<'t, T>>(loaned: L, _: &'t mut ()) -> T {
44 let mut place = MaybeUninit::uninit();
45 loaned.place(unsafe { &mut *(&mut place as *mut _) });
46 place.assume_init()
47}
48
49mod test_drop_cyclic {
50 /**
51 ```rust
52 use loaned::*;
53
54 struct Foo<'a>(&'a ());
55
56 type CyclicFoo<'a> = &'a mut Foo<'a>;
57 let (_, loaned): (CyclicFoo, _) = LoanedMut::loan(Box::new(Foo(&())));
58 drop!(loaned);
59 ```
60 */
61 mod no_drop {}
62
63 /**
64 ```rust
65 #![feature(dropck_eyepatch)]
66 use loaned::*;
67
68 struct Foo<'a>(&'a ());
69 unsafe impl<#[may_dangle] 'a> Drop for Foo<'a> { fn drop(&mut self) {} }
70
71 type CyclicFoo<'a> = &'a mut Foo<'a>;
72 let (_, loaned): (CyclicFoo, _) = LoanedMut::loan(Box::new(Foo(&())));
73 drop!(loaned);
74 ```
75 */
76 mod drop_eyepatch {}
77
78 /**
79 ```rust,compile_fail E0597
80 use loaned::*;
81
82 struct Foo<'a>(&'a ());
83 impl<'a> Drop for Foo<'a> { fn drop(&mut self) {} }
84
85 type CyclicFoo<'a> = &'a mut Foo<'a>;
86 let (_, loaned): (CyclicFoo, _) = LoanedMut::loan(Box::new(Foo(&())));
87 drop!(loaned);
88 ```
89 */
90 mod bad_drop {}
91}