Open
Description
Compiler version
3.0.2
Minimized code
It's often useful to architect modules with some shared parts, as in:
trait Shared:
class E
object ImplA extends Shared { /* ... */ }
object ImplB extends Shared { /* ... */ }
But we are kind of stuck when we want to provide type class instances that work on all shared parts. I think this approach ought to work, but currently does not:
trait Shared:
class E
given ImplA: Shared with { /* ... */ }
given ImplB: Shared with { /* ... */ }
// The type class of interest:
class Bar[A]
object Bar:
given (using s: Shared): Bar[s.E] = ???
Output
summon[Bar[ImplA.E]]
ambiguous implicit arguments of type Playground.Bar[Playground.ImplA.E] found for parameter x of method summon in object Predef.
I found:
Playground.Bar.given_Bar_E(
/* ambiguous: both object ImplA in object Playground and object ImplB in object Playground match type Playground.Shared */
summon[Playground.Shared]
)
But both object ImplA in object Playground and object ImplB in object Playground match type Playground.Shared.
summon[Bar[ImplA.E]](using Bar.given_Bar_E)
ambiguous implicit arguments: both object ImplA in object Playground and object ImplB in object Playground match type Playground.Shared of parameter s of given instance given_Bar_E in object Bar
summon[Bar[ImplA.E]](using Bar.given_Bar_E(using ImplA))
Ok.
Expectation
Implicit resolution should work out that the choice of ImplA
or ImplB
is not actually ambiguous.