Oh this is a fun one!
The following is maybe a bit hand-wavy with respect to some details.
let x = 42 <- at this point the compiler treats this as {integer}, that is it could be any of the integer types.
On the first x.abs() it now needs a concrete type, so it starts looking. It favors local implementations and finds your trait Abs that's implemented for i64. So it picks that and makes x: i64.
On the secondx.abs() it nows x: i64 and thus favors the direct implementation that Rust brings along: i64::abs. So it calls that, not your trait implementation. (you can btw see that if you e.g. add a println in your trait implementation, it only gets called once).
I didn't look if there's any issues filed about this that would have more discussion. But maybe with this explanation you'd be able to find some.
Thanks! I understand it now. This behavior surprises me!
Is it exactly defined in the rust reference? Or is it a breaking change and needs an edition gate if we make 2 syntactically identical method calls to resolve to the same method?