My nonacademic view is that implicit is by design not meant to work everytime it seems that it should work. I think it's a good idea otherwise you could easily get into an implicit hell. You could extend your example by adding more layers of implicit conversions. It would be hard to tell which function is actually called just by looking at the code. There are well-defined rules, but I remember simply that if it's not obvious from the code what's going on, it doesn't work.
I would say that your code breaks One-at-a-time Rule which leads to breaking the Non-Ambiguity Rule. A : S
is just a syntactic sugar, and can be rewritten to:
implicit class X[A](a: A)(implicit e: S[A]) { def foo() { } }
implicit class Y[A](a: A)(implicit e: T[A]) { def foo() { } }
Without resolution of the "second" implicit level (method argument e
) both classes X
and Y
look the same to the compiler and therefore are ambiguous. As the linked document says: "For sanity's sake, the compiler does not insert further implicit conversions when it is already in the middle of trying another implicit."