Allocations are not allowed in constants

Hi, I am new to Rust and I am trying to do exercise in the rust book: Storing Keys with Associated Values in Hash Maps - The Rust Programming Language (the pig latin exercise)

I am creating a constant called VOWELS that contains all the English vowels

pub const VOWELS: Vec<char> = vec!['a', 'i', 'u', 'e', 'o', 'A', 'I', 'U', 'E', 'O'];

but the compiler gives me error: allocation not allowed in constants

Does this happened because const variables are stored in stack?
Is there any way that I can declare array as const? As far as I learn, Vec in rust is array in other programming languages

thanks.

No, Rust also has plain old, ungrowable arrays. Which you have to use in const evaluation, because as you deduced correctly, you can't do heap allocations in constant contexts, as constant evaluation happens during compile time and not during runtime. The heap only exist during runtime. There are efforts to bring heap allocations to const eval, but I don't think you'll be able to do that any time soon.

As for your VOWELS, you can either declare it as an array or a slice:

pub const VOWELS_ARRAY: [char;10] = ['a', 'i', 'u', 'e', 'o', 'A', 'I', 'U', 'E', 'O'];
pub const VOWELS_SLICE: &[char] = &['a', 'i', 'u', 'e', 'o', 'A', 'I', 'U', 'E', 'O'];
2 Likes

Thank you, It worked now.

By the way, are there any pros/cons between using slice or array in this case? or is it only a matter of taste?

Hmm, I'd say arrays are stronger typed here, because they have the associated constant size. Its also easy to create a slice from an array, but it is hard to create an array from a slice, so arrays are more versatile. On the other hand they are more verbose, because you need to deal with the constant size. In your case adding the correct size is easy, because you know the length of the array. But if you were to generate the array differently, you'd have to get the right size somehow.

1 Like

No. You can store a vector itself on the stack. It's just that it always heap-allocates the internal buffer it manages, but you still can put the vec itself (ie, the pointer-length-capacity triple) on the stack.

The reason is exactly what the compiler pointed out. Const expressions are evaluated at compile time, and currently, the const evaluator doesn't support allocating memory.

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.