36

In the vec! macro implementation there is this rule:

($($x:expr),+ $(,)?) => (
    $crate::__rust_force_expr!(<[_]>::into_vec(box [$($x),+]))
);

What exactly is that <[_]> in it?

1
  • 6
    Whew, Rust is generally pretty readable and intuitive, but <[_]>:: looks like something straight out of an esolang. Commented Dec 19, 2021 at 18:45

2 Answers 2

30

Breaking down the specific parts of the syntax:

2
15

Let's go step by step to see how <[_]>::into_vec(box [$($x),+]) produces a Vec:

  1. [$($x),+] expands to an array of input elements: [1, 2, 3]
  2. box ... puts that into a Box. box expressions are nightly-only syntax sugar for Box::new: box 5 is syntax sugar for Box::new(5) (actually it's the other way around: internally Box::new uses box, which is implemented in the compiler)
  3. <[_]>::into_vec(...) calls the to_vec method on a slice containing elements that have an inferred type ([_]). Wrapping the [_] in angled brackets is needed for syntactic reasons to call an method on a slice type. And into_vec is a function that takes a boxed slice and produces a Vec:
    pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> {
        // ...
    }
    

This could be done in many simpler ways, but this code was fine-tuned to improve the performance of vec!. For instance, since the size of the Vec can be known in an advance, into_vec doesn't cause the Vec to be reallocated during its construction.

Not the answer you're looking for? Browse other questions tagged or ask your own question.