Macro moveit::moveit

source ·
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.