shepmaster / snafu

Easily assign underlying errors into domain-specific errors while adding context
https://docs.rs/snafu/
Apache License 2.0
1.39k stars 60 forks source link

Const generics seem to be giving the derive macro trouble #436

Closed chanced closed 6 months ago

chanced commented 7 months ago

I'm moving one of my libs over to snafu but I've run into an issue with an error that uses const generics. It compiles if I remove the Snafu derive.

#[derive(Debug, Snafu)]
#[snafu(display(
    "the length of a string or slice overflows the maximum of {}, received {}",
    Self::M,
    value
))]
pub struct OverflowError<Value, const M: u64 = { u32::MAX as u64 }> {
    value: Value,
}
error[E0412]: cannot find type `M` in this scope
 --> src/main.rs:8:39
  |
8 | pub struct OverflowError<Value, const M: u64 = { u32::MAX as u64 }> {
  |                                       ^ not found in this scope
  |
help: you might be missing a type parameter
  |
8 | pub struct OverflowError<Value, M, const M: u64 = { u32::MAX as u64 }> {
  |                               +++

error[E0412]: cannot find type `M` in this scope
 --> src/main.rs:8:39
  |
8 | pub struct OverflowError<Value, const M: u64 = { u32::MAX as u64 }> {
  |                                       ^ not found in this scope

error[E0747]: unresolved item provided when a constant was expected
 --> src/main.rs:8:39
  |
8 | pub struct OverflowError<Value, const M: u64 = { u32::MAX as u64 }> {
  |                                       ^
  |
help: if this generic argument was intended as a const parameter, surround it with braces
  |
8 | pub struct OverflowError<Value, const { M }: u64 = { u32::MAX as u64 }> {
  |                                       +   +

Some errors have detailed explanations: E0412, E0747.
For more information about an error, try `rustc --explain E0412`.
error: could not compile `rust` (bin "rust") due to 9 previous errors
MarkDDR commented 7 months ago

A more minimal example

#[derive(Snafu)]
pub struct Foo<const N: i32> {}

This code does not compile with the derive macro present, with the following error. If you take away the derive macro, it compiles normally

error[E0412]: cannot find type `N` in this scope
 --> src/main.rs:4:22
  |
4 | pub struct Foo<const N: i32> {}
  |                      ^ not found in this scope

error[E0747]: unresolved item provided when a constant was expected
 --> src/main.rs:4:22
  |
4 | pub struct Foo<const N: i32> {}
  |                      ^
  |
help: if this generic argument was intended as a const parameter, surround it with braces
  |
4 | pub struct Foo<const { N }: i32> {}
  |                      +   +
shepmaster commented 7 months ago

See #438