unlist

Macro unlist 

Source
macro_rules! unlist {
    ([$($patterns:tt)*] = $val:expr $(;)?) => { ... };
}
Expand description

Destructures an NList by value into its elements

This macro uses the same syntax as array patterns, with the limitation that it only supports .. patterns at the end.

§Motivation

This macro exists because, as of Rust 1.83, destructuring generic NLists by value in const fns with nlist_pat causes “destructor cannot be evaluated in const fn” errors.

Note: destructuring into nested non-Copy fields isn’t supported in the aforementioned generic const fn context, you’ll need to bind the NList element to a variable, then destructure the variable with konst::destructure.

§Example

use nlist::{NList, PeanoInt, Peano, nlist, peano, unlist};
 
assert_eq!(multisplit(nlist![3, 5]), (3, 5, nlist![]));
assert_eq!(multisplit(nlist![8, 13, 21]), (8, 13, nlist![21]));
assert_eq!(multisplit(nlist![34, 55, 89, 144]), (34, 55, nlist![89, 144]));
 
const fn multisplit<T, L>(list: NList<T, peano::Add<Peano!(2), L>>) -> (T, T, NList<T, L>)
where
    L: PeanoInt
{
    unlist!{[a, b, c @ ..] = list}
     
    (a, b, c)
}

If the unlist!{...} line is replaced with

    let nlist_pat![a, b, c @ ..] = list;

it causes this compilation error as of Rust 1.83.0:

error[E0493]: destructor of `NList<T, nlist::PlusOne<nlist::PlusOne<L>>>` cannot be evaluated at compile-time
  --> src/macros/destructuring_macros.rs:134:27
   |
6  | const fn multisplit<T, L>(list: NList<T, peano::Add<Peano!(2), L>>) -> (T, T, NList<T, L>)
   |                           ^^^^ the destructor for this type cannot be evaluated in constant functions
...
12 | }
   | - value is dropped here