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}