Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implicit resolution discards inherited overloads with implicit parameters #11522

Closed
jcracknell opened this issue May 8, 2019 · 1 comment
Closed

Comments

@jcracknell
Copy link

jcracknell commented May 8, 2019

Possibly related to and/or fixed by #10526, this differs in that the generated error is confusing:

class A

object A extends AA {
  implicit def a(implicit s: String): A = new A
}

trait AA {
  implicit def a(implicit i: Int): A = new A
}

class B

object B {
  implicit def b(implicit s: String): B = new B
  implicit def b(implicit i: Int): B = new B
}

class C

object C extends CC {
  implicit def c(implicit i: Int): C = new C
}

trait CC {
  implicit def c(implicit s: String): C = new C
}

object program {
  implicit def i: Int = 42

  implicitly[A]
  implicitly[B]
  implicitly[C]
}

Produces:

test.scala:31: error: could not find implicit value for parameter e: A
  implicitly[A]
            ^
test.scala:32: error: ambiguous reference to overloaded definition,
both method b in object B of type (implicit i: Int)B
and  method b in object B of type (implicit s: String)B
match expected type B
  implicitly[B]
            ^
two errors found

Here the error message in the case of A makes no sense at all (obviously there is an implicit value for A). C compiles despite the fact that CC.c will never be a candidate for implicit resolution.

@som-snytt
Copy link

This is correct, and I don't understand the commentary.

Does -Xlog-implicits make it more clear?

The overloaded a prefers the one in the subclass which takes a String, so that fails. The compiler doesn't magically forget about overloading in order to use the other method that takes an implicit that happens to be available.

C is just the inverse case, so I especially don't understand the commentary.

In other words, to summon an implicit A, there are some methods available that result in A. Because they are both named a, normal overloading resolution applies to pick one. The spec says, whatever a refers to is what you get.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants