trait implementation hidden by where clause

3232611
Opened by Trevor Spiteri at 2024-12-21 05:01:44

In both cases in the code below, the trait implementation impl Op<()> for Single seems to be hidden by the clause where Single: Op<T>. Using universal function call syntax works as a workaround.

trait Op<T> {
    fn op(&self, t: T);
}

struct Single;

impl Op<()> for Single {
    fn op(&self, _t: ()) {}
}

struct Pair {
    a: Single,
    b: Single,
}

// case 1
fn foo<T>(pair: Pair, t: T)
where
    Single: Op<T>,
{
    pair.a.op(t);
    // this fails to compile:
    pair.b.op(());
    // this works: <Single as Op<()>>::op(&pair.b, ());
}

// case 2
impl<T> Op<T> for Pair
where
    Single: Op<T>,
{
    fn op(&self, t: T) {
        self.a.op(t);
        // this fails to compile:
        self.b.op(());
        // this works: <Single as Op<()>>::op(&self.b, ());
    }
}

The error messages:

error[E0308]: mismatched types
  --> lib.rs:23:15
   |
23 |     pair.b.op(());
   |               ^^ expected type parameter, found ()
   |
   = note: expected type `T`
              found type `()`

error[E0308]: mismatched types
  --> lib.rs:35:19
   |
35 |         self.b.op(());
   |                   ^^ expected type parameter, found ()
   |
   = note: expected type `T`
              found type `()`
  1. Triage: no change

    Maayan Hanin at 2022-03-21 18:02:01

  2. Smaller repro: #119617.

    León Orell Valerian Liehr at 2024-01-06 00:33:10