Skip to content

Ambiguous overload on functions differing by implicits #13768

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

Closed
Adam-Vandervorst opened this issue Oct 18, 2021 · 2 comments
Closed

Ambiguous overload on functions differing by implicits #13768

Adam-Vandervorst opened this issue Oct 18, 2021 · 2 comments

Comments

@Adam-Vandervorst
Copy link

Adam-Vandervorst commented Oct 18, 2021

Compiler version

3.0.2

Minimized code

class Base
class A extends Base
class B extends Base

trait T[X]

given T[A]()


def f[X <: Base](ins: X)(using T[X]) = "with T"
def f[X <: Base](ins: X) = "without T"

@main def m = f(A())

Output

Ambiguous overload. The overloaded alternatives of method f with types
 [X <: Base](ins: X)(using x$2: T[X]): String
 [X <: Base](ins: X): String
both match arguments (A)
  f(A())

Expectation

To work similar to the regular case:

def f[X <: Base](ins: X)(t: T[X]) = "with T"
def f[X <: Base](ins: X) = "without T"

I first suspected this to be an issue with the implicit being optional in that case, but the following doesn't work either:

def f[X <: Base](ins: X)(using T[X]) = "with T"
def f[X <: Base](ins: X)(using NotGiven[T[X]]) = "without T"
@Adam-Vandervorst
Copy link
Author

Adam-Vandervorst commented Oct 18, 2021

This is a real problem for more complex constructions like:

def extractTest[K <: Finite[F], F](k: K): TestElements[F] = fromFinite[F](using k)
def extractTest[K <: CompleteJoinLattice[F], F](k: K)(using t: TestElements[F]): TestElements[F] = t

where there is only one ambigious case; K inheriting from Finite[F] and having a type parameter with the TestElements type class. In general I expect the NotGiven construction to work here.

Moving this to a match

transparent inline def extractTest[K <: CompleteJoinLattice[F], F](k: K) = (k: K) match
  case kv: Finite[f] => fromFinite[f](using kv)
  case _ => summonInline[TestElements[F]]

fails on the same case, though with a different error:

no implicit argument of type TestElements[Set[Boolean]] was found.

which is misleading, because it does find the implicit when K does not inherit from Finite.
This error can finally be resolved by inlining that match too:

transparent inline def extractTest[K[F], F](k: K[F]) = inline k match
  case kv: Finite[F] => fromFinite[F](using kv)
  case _ => summonInline[TestElements[F]]

@smarter
Copy link
Member

smarter commented Dec 20, 2021

I think the explanation in #17794 also applies here so I'm closing this as duplicate.

@smarter smarter closed this as completed Dec 20, 2021
@SethTisue SethTisue changed the title Ambigious overload on functions differing by implicits Ambiguous overload on functions differing by implicits Dec 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants