Consider the following (very cut down) code. It will not compile, on the self.is_x() call with "cannot infer type for type parameter S declared on the trait Refiner". I'm not completely sure what the problem is, and I'm also not sure how to fix it -- how can I "type annotate" self?
fn name(&self) -> usize {
if <Self as Refiner<()>>::is_x(self) { 2 } else { 3 }
}
The problem is that
the compiler sees that Q: Refiner<T> for every T, because of your blanket impl
whenever you try to call a Refiner method like is_x on a value foo of type Q, the compiler sees <Q as Refiner<???>>::is_x(&foo) and has no idea what type to put in the blank, because of the previous point
in fact any type would give the same result, again because of the blanket impl, but the compiler is not aware of that
So you must specify the generic parameter explicitly.
ETA: I just discovered on the playground that you can actually omit the Self type: <_ as Refiner<()>>::is_x(self). Cool!
Yeah, I just used () because the blanket impl makes it clear that the actual type doesn't matter (and the compiler didn't complain about T being unused), but in general re-using T here is the better practice.