rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.96k stars 12.69k forks source link

Wrong error message (E401) when storing the result of a generic const fn inside a const member of a generic function #68373

Open sm-Fifteen opened 4 years ago

sm-Fifteen commented 4 years ago

I tried this code, assuming the result of size_of::<T>() would be considered a constant value since it would be known at function monomorphization:

const fn size_plus_one<T:Sized>() -> usize {
    const size: usize = ::core::mem::size_of::<T>();

    size + 1
}

This resulted in the following compilation error:

error[E0401]: can't use generic parameters from outer function
 --> src/lib.rs:2:48
  |
1 | const fn size_plus_one<T:Sized>() -> usize {
  |                        - type parameter from outer function
2 |     const size: usize = ::core::mem::size_of::<T>();
  |                                                ^ use of generic parameter from outer function

As it turns out, the error message here is incorrect, and the issue can be solved by using let instead, something the error message was rather unhelpful with.

const fn size_plus_one<T:Sized>() -> usize {
    let size: usize = ::core::mem::size_of::<T>();

    size + 1
}

PLAYGROUND LINK

Meta

rustc 1.40.0 (73528e339 2019-12-16)
binary: rustc
commit-hash: 73528e339aae0f17a15ffa49a8ac608f50c6cf14
commit-date: 2019-12-16
host: x86_64-unknown-linux-gnu
release: 1.40.0
LLVM version: 9.0
jonas-schievink commented 4 years ago

Note that the message is technically correct – const defines an item, and items (other than impl and trait items) don't inherit generic parameters from the thing they're defined in.

sm-Fifteen commented 4 years ago

Yes, I realize that now. It makes sense why const was innapropriate in that context (I had the wrong impression on how const would work inside const fns), it's just that the error message wasn't very helpful, and looking it up didn't provide any information about my case.