0

I have a problem in which a child trait constraint on parent trait doesn't apply. Here is a simple example:

trait ValueGetter {
    type ValueType;

    fn get_value() -> Self::ValueType;
}

trait DebugValueGetter: ValueGetter
where
    Self::ValueType: std::fmt::Debug,
{
}

fn function<DVG: DebugValueGetter>(debug_value_getter: DVG) {
    todo!()
}

For some reason, rust says:

error[E0277]: `<DVG as ValueGetter>::ValueType` doesn't implement `Debug`
  --> src\main.rs:13:18
   |
13 | fn function<DVG: DebugValueGetter>(debug_value_getter: DVG) {
   |                  ^^^^^^^^^^^^^^^^ `<DVG as ValueGetter>::ValueType` cannot be formatted using `{:?}` because it doesn't implement `Debug`
   |
   = help: the trait `Debug` is not implemented for `<DVG as ValueGetter>::ValueType`
note: required by a bound in `DebugValueGetter`
  --> src\main.rs:9:22
   |
7  | trait DebugValueGetter: ValueGetter
   |       ---------------- required by a bound in this trait
8  | where
9  |     Self::ValueType: std::fmt::Debug,
   |                      ^^^^^^^^^^^^^^^ required by this bound in `DebugValueGetter`
help: consider further restricting the associated type
   |
13 | fn function<DVG: DebugValueGetter>(debug_value_getter: DVG) where <DVG as ValueGetter>::ValueType: Debug {
   |                                                             ++++++++++++++++++++++++++++++++++++++++++++

My expectation was that the where on DebugValueGetter would constraint such that you cannot implement DebugValueGetter for ValueGetter if ValueGetter::ValueType doesn't implement Debug, but it seems the constraint falls separately on the usage of the trait.

Is there a proper way to get the outcome I desire? Is this intended?

Omer Lubin
  • 551
  • 2
  • 8
  • 24
  • 1
    I think this is just a limitation of the trait solver – PitaJ Apr 05 '23 at 20:46
  • @PitaJ It seems to not be a constraint - but just a weird language quirk. It actually does everything right. The additional `where` would be useful if I wanted to limit the type even more for the function, but even when I don't, and the constraint is obvious, it still requires me to add the `where`. – Omer Lubin Apr 05 '23 at 20:51
  • 1
    By "limitation of the trait solver", I didn't mean a requirement on the user, I meant a shortcoming of the compiler. – PitaJ Apr 05 '23 at 20:55
  • You may want to shift this to a function on the main `ValueGetter` trait that's gated with `where Self::ValueType : Debug`. – tadman Apr 05 '23 at 21:49
  • It's for this reason that it is recommended to put constraints on the `impl` rather than the `trait` or `struct` declaration. I'm pretty sure there is a duplicate somewhere, although I can't find it right now. – Jmb Apr 06 '23 at 07:36
  • Relevant: https://stackoverflow.com/a/66369912/5397009 – Jmb Apr 06 '23 at 07:47

0 Answers0