Incorrect error msg regarding const fn generic usage

#1

When I try to compile:

fn foo<T : Sized> ()
{
    use ::std::mem::size_of;
    let array = [(); size_of::<T>()];
}

fn main () {}

I get the following error msg:

error[E0277]: the size for values of type `T` cannot be known at compilation time
 --> <anon>:4:22
  |
4 |     let array = [(); 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/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
  = help: consider adding a `where T: std::marker::Sized` bound
  = note: required by `std::mem::size_of`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.

whilst there clearly is a T : Sized trait bound. I am not that surprised that the code errors, since I am, after all, trying to use the return value of a generic function in a place requiring a const expression (even though ::std::mem::size_of is a const fn), but I expected a more accurate error message. Being told by the compiler that I need a T : Sized bound when there clearly is such bound does not feel right.

And in an ideal world, it should even compile, since after monomorphisation the size should indeed be known, but that’s another issue and I imagine there might be technical reasons forbidding this.

#2

Probably related:

#3

Right now we don’t have const generics, therefore, there is no way to use generic parameters in array lengths in any way.

1 Like
#4

Ok I see, I never would have though that fixing an error message would be as hard fixing the whole ordeal ^^’
Fair enough, let’s wait for const generics to be shipped then :slight_smile:
(thread can be closed, now)

#5

Take a look at generic-array. It’s a nice solution leveraging typenum.

#6

Thanks, I knew about ::typenum and I really like their getting type-level integers into Rust (I wish they become one day part of the language with the expected sugar).

For my need case, however, ::generic-array won’t do; I was trying to get to statically constrain that T and U be the same size (without using transmute) by having a type-level equality constraint: [(); size_of::<T>()] == [(); size_of::<U>()]