Generic tuple struct type parameter default ignored?

trait Unsigned {}

impl Unsigned for u32 {}
impl Unsigned for u64 {}

struct Foo<T = u32>(pub T)
where
    T: Unsigned;

fn main() {
    let _ = Foo(456);
}

I would expect this code to compile and instantiate a Foo with a u32. However it fails with the error below. Is this a bug, an unsupported feature, or a mistake on my part?

error[E0277]: the trait bound `i32: Unsigned` is not satisfied
  --> src/main.rs:11:13
   |
6  | / struct Foo<T = u32>(pub T)
7  | | where
8  | |     T: Unsigned;
   | |________________- required by `Foo`
...
11 |       let _ = Foo(456);
   |               ^^^ the trait `Unsigned` is not implemented for `i32`

error[E0277]: the trait bound `i32: Unsigned` is not satisfied
  --> src/main.rs:11:13
   |
6  | struct Foo<T = u32>(pub T)
   |        --- required by a bound in this
7  | where
8  |     T: Unsigned;
   |        -------- required by this bound in `Foo`
...
11 |     let _ = Foo(456);
   |             ^^^^^^^^ the trait `Unsigned` is not implemented for `i32`

Defaults only apply when specifying the type of something, i.e. this compiles:

trait Unsigned {}

impl Unsigned for u32 {}
impl Unsigned for u64 {}

struct Foo<T = u32>(pub T)
where
    T: Unsigned;

fn main() {
    let foo: Foo = Foo(456);
}

But when using the constructor, the default does not apply, because otherwise you could not construct it with any other T than the default without typing Foo::<_>(value)

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.