When you do x.f(x.0), you have borrowed x to provide the &mut self to f before trying to borrow x again to get a reference to x.0. It is not possible to refer to x.0 twice at the same time. That is, the method f can't have both mutable access to x via &mut self (which includes x.0) and a seemingly immutable reference to x.0 at the same time.
When using a temporary variable, you actually get a copy of the value; this means you no longer refer to that int in X but 42. That's allowed.
Regarding the "non-lexical lifetimes" comments: Since f takes a good old u32 instead of a reference to it, x.f(x.0) should basically be equivalent to x.f(42), because the compiler can let go of x after getting the value out of x.0 and then mut-borrow x again to provide &mut self to f. However, the compiler determines the lifetimes and their requirements very early on during compilation; lifetimes are therefor currently broader than they have to be. rustc is currently unable to determine that the borrow on x due to the x.0 argument has ended before borrowing x for &mut self. There is work underway to fix this.