pub struct LoanedMut<'t, T> { /* private fields */ }
Expand description
LoanedMut<'t, T>
connotes ownership of a value T
, with the caveat that
allocations owned by it are mutably loaned for 't
(i.e. something else may
hold an &'t mut
reference to such allocations).
Thus, for the duration of 't
, one cannot access this value.
One can, however, store this value somewhere with LoanedMut::place
,
which will ensure that it cannot be used for the duration of 't
.
Taking the value out of a LoanedMut
can be done with the take!
macro,
which will statically ensure that 't
has expired.
§Dropping
The value held by a LoanedMut
can only be dropped once 't
expires. Since
there is no way in the type system to enforce this, nor any way to check
this at runtime, dropping a LoanedMut
panics.
If leaking is intentional, use a ManuallyDrop<LoanedMut<'t, T>>
.
To drop the inner value, use the drop!
macro, which will statically ensure
that 't
has expired.
Implementations§
Source§impl<'t, T> LoanedMut<'t, T>
impl<'t, T> LoanedMut<'t, T>
Sourcepub fn loan(value: T) -> (&'t mut T::Target, Self)
pub fn loan(value: T) -> (&'t mut T::Target, Self)
Constructs a LoanedMut
from a given smart pointer, returning the mutable
borrow along with the loaned pointer.
Sourcepub fn new(value: T) -> Self
pub fn new(value: T) -> Self
Creates a LoanedMut
without actually loaning it. If you want to loan it,
use LoanedMut::loan
.
Sourcepub fn place(self, place: &'t mut impl Place<'t, T>)
pub fn place(self, place: &'t mut impl Place<'t, T>)
Stores the contained value into a given place. See the Place
trait for
more.
Examples found in repository?
12fn main() {
13 // First, we create a single node `a`, which has two holes, `b` and `c`.
14 // ```text
15 // a
16 // / \
17 // ?b ?c
18 // ```
19 // `a` is a `LoanedMut<Tree>`, whilst `b` and `c` are `&mut Tree`s.
20 let (a, b, c) = new_node();
21
22 // Next, we fill one of those holes, `b`, with a leaf:
23 // ```text
24 // a
25 // / \
26 // 1 ?c
27 // ```
28 *b = Tree::Leaf(1);
29
30 // Now, we create another node, `x`, with holes `y` and `z`:
31 // ```text
32 // a x
33 // / \ / \
34 // 1 ?c ?y ?z
35 // ```
36 let (x, y, z) = new_node();
37
38 // We fill `y` with another leaf:
39 // ```text
40 // a x
41 // / \ / \
42 // 1 ?c 2 ?z
43 // ```
44 *y = Tree::Leaf(2);
45
46 // Now, we fill the hole `c` with the node `x`.
47 // ```text
48 // a
49 // / \
50 // 1 / \
51 // 2 ?z
52 // ```
53 // We still have a mutable reference to the hole `z`, even though we just
54 // moved ownership of `x` – this is the key power of `Loaned` values.
55 x.place(c); // this is like `*c = x`, except it accepts `Loaned` values.
56
57 // Finally, we can fill the hole `z` (which is a mutable reference to data now owned by `a`):
58 // ```text
59 // a
60 // / \
61 // 1 / \
62 // 2 3
63 // ```
64 *z = Tree::Leaf(3);
65
66 // All of the borrows have expired, so we can now take the tree out of `a`:
67 let a = take!(a);
68
69 println!("{a:?}");
70 assert_eq!(format!("{a:?}"), "Node(Leaf(1), Node(Leaf(2), Leaf(3)))");
71
72 // If we tried to use one of the borrows now, we would get an error from the borrow checker.
73 // *z = Tree::Leaf(0xBAD);
74}
Source§impl<'t, T> LoanedMut<'t, T>
impl<'t, T> LoanedMut<'t, T>
Sourcepub fn merge(
value: T,
f: impl for<'i> FnOnce(&'i mut T, &'i MergeMut<'t, 'i>),
) -> Self
pub fn merge( value: T, f: impl for<'i> FnOnce(&'i mut T, &'i MergeMut<'t, 'i>), ) -> Self
Merges multiple LoanedMut
values.
§Example
use loaned::LoanedMut;
let a = LoanedMut::new(1);
let b = LoanedMut::new(2);
let ab: LoanedMut<(u32, u32)> = LoanedMut::merge(Default::default(), |ab, m| {
m.place(a, &mut ab.0);
m.place(b, &mut ab.1);
});
Source§impl<'t, T> LoanedMut<'t, T>
impl<'t, T> LoanedMut<'t, T>
Sourcepub fn loan_with<L>(
value: T,
f: impl for<'i> FnOnce(&'i mut T, &'i LoanWithMut<'t, 'i>) -> L,
) -> (L, Self)
pub fn loan_with<L>( value: T, f: impl for<'i> FnOnce(&'i mut T, &'i LoanWithMut<'t, 'i>) -> L, ) -> (L, Self)
Creates a LoanedMut
with multiple sub-loans.
§Example
use loaned::LoanedMut;
let ((a, b), ab) = LoanedMut::loan_with((Box::new(0), Box::new(0)), |ab, l| {
(l.loan_mut(&mut ab.0), l.loan_mut(&mut ab.1))
});
*a = 1;
*b = 2;
assert_eq!(loaned::take!(ab), (Box::new(1), Box::new(2)));
Examples found in repository?
76fn new_node<'t>() -> (LoanedMut<'t, Tree>, &'t mut Tree, &'t mut Tree) {
77 let ((left, right), root) = LoanedMut::loan_with(
78 Tree::Node(Default::default(), Default::default()),
79 |tree, l| {
80 let Tree::Node(left, right) = tree else {
81 unreachable!()
82 };
83 (l.loan_mut(left), l.loan_mut(right))
84 },
85 );
86 (root, left, right)
87}