macro_rules! moveit {
(let $name:ident $(: $ty:ty)? = &move *$expr:expr $(; $($rest:tt)*)?) => { ... };
(let mut $name:ident $(: $ty:ty)? = &move *$expr:expr $(; $($rest:tt)*)?) => { ... };
(let $name:ident $(: $ty:ty)? = &move $expr:expr $(; $($rest:tt)*)?) => { ... };
(let mut $name:ident $(: $ty:ty)? = &move $expr:expr $(; $($rest:tt)*)?) => { ... };
(let $name:ident $(: $ty:ty)? = $expr:expr $(; $($rest:tt)*)?) => { ... };
(let mut $name:ident $(: $ty:ty)? = $expr:expr $(; $($rest:tt)*)?) => { ... };
($(;)?) => { ... };
(&move *$expr:expr) => { ... };
(&move $expr:expr) => { ... };
($expr:expr) => { ... };
(@move $(($mut:tt))? $name:ident, $($ty:ty)?, $expr:expr) => { ... };
(@put $(($mut:tt))? $name:ident, $($ty:ty)?, $expr:expr) => { ... };
(@emplace $(($mut:tt))? $name:ident, $($ty:ty)?, $expr:expr) => { ... };
}
Expand description
Performs an emplacement operation.
This macro allows for three exotic types of let
bindings:
let bx = Box::new(42);
moveit! {
// Use a `New` to construct a new value in place on the stack. This
// produces a value of type `Pin<MoveRef<_>>`.
let x = new::default::<i32>();
// Move out of an existing `DerefMove` type, such as a `Box`. This has
// type `MoveRef<_>`, but can be pinned using `MoveRef::into_pin()`.
let y = &move *bx;
// Create a `MoveRef` of an existing type on the stack. This also has
// type `MoveRef<_>`.
let z = &move y;
}
All three lets
, including in-place construction, pin to the stack.
Consider using something like Box::emplace()
to perform construction on
the heap.
This macro also has temporary forms, where rather than creating a binding, a temporary (which cannot outlive its complete expression) is created:
fn do_thing(x: Pin<MoveRef<i32>>) {
// ...
}
do_thing(moveit!(new::of(42)));
Note that these bindings cannot outlive the subexpression:
ⓘ
let x = moveit!(new::of(42));
let y = *x; // Borrow checker error.