Bad type inference? expected type parameter "U", found integer

Hi! I'm implementing a range type which has multiple ranges, for which I wanted to impl RangeBounds (in second thought this may be not needed)..
In any case, while trying to implement a proper fn contains(), I found this error which I don't think it should happen as all types involved in the expression are usize:

struct Foo {
    r: Vec<usize>,
}

impl Foo {
    fn contains<U>(&self, item: &U) -> bool
    where
        usize: PartialOrd<U>,
        U: ?Sized + PartialOrd<usize>,
    {
        if self.r.is_empty() {
            return false;
        }
        if let Some(pos) = self.r.iter().position(|v| v < item) {
            (pos % 2) == 0  // error
        } else {
            false
        }
    }
}

(Playground link)

I get error E0308 in line 15.

If I put the offending expression in a new function and using it, the code compiles fine...

Is this error OK?

I think the problem is that type inference gives priority to the function bounds over the known implementations. This leads to prefer the usize: PartialOrd<U> (which implies usize: PartialEq<U>) over the impl PartialEq for usize in the stdlib.
I don't exactly know why it works like this, but I guess there must be a good reason.

You can add a usize: PartialEq bound to make it work without additional functions.

1 Like

You're right, adding usize: PartialEq makes the issue go away, even when impl RangeBounds .. it's like it is remembering the compiler that usize is PartialEq :laughing:

Thanks!

Looks like yet another instance of this issue, probably?

It seems pretty similar!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.