I think I have isolated the reason. Overloading resolution prefers values x over parameterless method accessors x. In the first case, we have two implicits as fields, and both are accessed with parameterless method accessors. So ambiguity results. In the second case, the local variable is treated as more specific in overloading resolution. This is not justified by the spec, which treats fields and parameterless methods the same. But changing it might break existing code, so we have to tread carefully here.
Turns out my previous reasoning was completely incorrect. The compiler does indeed treat values and parameterless methods the same, just as the spec demands. The reason why the second example slipped through is considerably more devious: When checking the Foo.x' implicit, a CyclicReference error occurs which causes the alternative to be discarded. Why a CylicReference? Because the inferencer tries to decide whether the owner of zis a subclass of the owner odx. To do this, it computed the info of the owner of z1, which is not complete because no result type for f1` was given. Hence a CyclicReference error.
The fix is twofold: (1) We make isNonBottomSubClass smarter so that it always returns false if the symbol in question is not a type; hence the info need not be computed. (2) It's dubious to swallow CyclicReference errors anywhere, but I deemed it too risky to propagate them. But at least the CyclicReference is now logged if -Ylog-implicit is true. This hopefully spares future maintainers the same detective work I had to go through when digging this out.
Leaving for Paul to close once pull request is accepted.