Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't Rust use the size of a generic parameter as an array length? [duplicate]

I'm having a bit of trouble understanding the problem with this code:

fn doesnt_compile<T>() {
    println!("{}", std::mem::size_of::<[T; std::mem::size_of::<T>()]>());
}

fn main() {
    doesnt_compile::<i32>();
}

When run in the playground (or on my machine) the compiler seems to ignore the implicit trait bound 'Sized' for T.

This is the error:

error[E0277]: the size for values of type `T` cannot be known at compilation time
   --> src/main.rs:2:64
    |
2   |     println!("{}", std::mem::size_of::<[T; std::mem::size_of::<T>()]>());
    |                                                                ^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `T`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where T: std::marker::Sized` bound

I stared at it for a while and tried to rewrite it in different ways, but i can't figure out why it shouldn't compile. I find it especially confusing since the following code works just fine:

fn compiles<T>() {
    println!("{}", std::mem::size_of::<T>());
}

fn main() {
    compiles::<i32>();
}

Is there something I'm missing? Is it a compiler bug?

like image 577
Plettro Avatar asked Dec 18 '19 09:12

Plettro


People also ask

How to determine the size of various types in rust?

This function is in core::mem::size_of and takes a type and returns its size in bytes. Let us learn how to use the size_of function to determine the size of various types in Rust.

Why can't arrays be generic?

This has long caused problems with arrays, because arrays have an integer as part of their type; [T; N] is the type of an array of type T of N length. Because there is no way to be generic over N, you have to manually implement traits for arrays for every N you want to support.

What is the size limit of an array in rust?

Before 1.47.0, there is the Rust array size limit size of 32. This is evident when we get the E0277 error that has the following message. 1 When Do We Get The Error?

Why can't I use _ in an array type?

In array types, the length is not a type, but an expression, and _ cannot be used in expressions. What you can do, though, is append f32 to only one of the literals and omit the type completely. Since all the items of an array must have the same type, the compiler will infer the correct element type for the array.


1 Answers

This is the result of a known compiler bug (#43408). Array length expressions cannot currently have type parameters, and apparently it isn't even possible to improve the error message without major refactoring.

There currently isn't a good workaround for this in general, though there might be one for your specific use case.

like image 142
Sven Marnach Avatar answered Sep 22 '22 20:09

Sven Marnach