Type-inference breaks depending on the order of arguments in a function call

bd7cda8
Opened by gnzlbg at 2022-10-16 17:52:51

Given (playground link):

pub trait Int { fn zero() -> Self; }

impl Int for u8 { fn zero() -> u8 { 0 } }
impl Int for i8 { fn zero() -> i8 { 0 } }

pub trait FromSigned<T> {
    fn from_signed(T) -> Self;
}

impl<T: Int, U: Int> FromSigned<T> for U {
    fn from_signed(x: T) -> U {
        U::zero()
    }
}

pub fn from_signed<To, Fr>(x: Fr) -> To
    where Fr: Int,
          To: FromSigned<Fr>
{
    To::from_signed(x)
}

I ran into the following:

fn main() {
    // This type-checks:
    255u8 == from_signed(-1i8); 
    // This doesn't type checkL
    from_signed(-1i8) == 255u8; 
}

In particular, my intuition says that a == b desugars into equals(a, b). That equals(a, b) type-checks but equals(b, a) doesn't is extremely weird, in particular since equals expects both arguments to be of the same type.

  1. equals only defaults to both arguments being the same type, it might also be any other type. But it would be very convenient if either certain operators were treated as symmetric, or at least a hint were given that swapping the arguments will typeck

    Oli Scherer at 2017-01-20 15:47:44

  2. triage: still reproduces on rustc 1.64.0 (a55dd71d5 2022-09-19)

    Maayan Hanin at 2022-10-16 17:52:51