Type inference success for Iterator::sum depends on order of arguments in assert_eq!

The following compiles and runs fine

let x = vec![1, 2, 3].iter().sum();
assert_eq!(6, x);

but if I swap the order of 6 and x, it fails to compile unless I annotate x: i32. I get that sum requires explicit annotation in most cases, but I'm just confused in this case why one order of the assert works fine without explicit annotation, but other one does not.

ChatGPT says it's because the assert_eq! in the second case "needs to typecheck x first, and it doesn't know the type there so is stuck", but I don't find that clear or convincing.

There's another thread with similar name, but that one is about Vec compared to Array, for which traits in one direction exists but other does not, so is not relevant for my question

1 Like

assert_eq!(a, b) (or just plain equality a == b) uses the PartialEq::eq trait method, with the first parameter as the &self argument. When calling a trait method, the receiver (self) must already have a known type so that Rust can resolve the correct method implementation.

In the case of Iterator::sum(), the return type is generic and must be inferred or explicitly specified. If you use the result of sum() as the right-hand side of PartialEq::eq, Rust can infer its type from the left-hand side; for example, from a concrete literal like 6, inferring that you’re comparing two i32s.

However, if the result of sum() is used as the receiver (i.e., the left-hand side of ==), Rust must know its type up front to select the correct PartialEq impl. Since it doesn't yet know the result type of sum(), and there's no prior constraint, inference fails.