bug
bug copied to clipboard
Implicit resolution bug in scalac (working in dotty)
I didn't get an answer on the scala list, and don't see this particular case already on the bug tracker. Then again, i don't really understand why this isn't working, so i may have missed it.
Repro example showing the failure:
trait ShapeLevel
trait FlatShapeLevel extends ShapeLevel
trait ColumnsShapeLevel extends FlatShapeLevel
abstract class Shape[Level <: ShapeLevel, -Mixed_, Unpacked_, Packed_]
object Shape extends TupleShapeImplicits { }
trait TupleShapeImplicits {
implicit final def tuple2Shape[Level <: ShapeLevel, M1,M2, U1,U2, P1,P2](
implicit u1: Shape[_ <: Level, M1, U1, P1],
u2: Shape[_ <: Level, M2, U2, P2]):
Shape[Level, (M1,M2), (U1,U2), (P1,P2)] = ???
}
class Query[A, B] {
def map[C, D](f: (A) => C)(implicit shape: Shape[_ <: FlatShapeLevel, C, D, _]) = ???
}
// This works, but is too restrictive on the `Level` of the implicit shape
def pairItGood[A, B](q: Query[A, B])(implicit shape: Shape[FlatShapeLevel, A, B, _]) =
q.map(x => (x, x))
// This works, since i've given it the 'hint' to use the `tuple2Shape` (no-longer-)implicit def
def pairItHint[A, B](q: Query[A, B])(implicit shape: Shape[_ <: FlatShapeLevel, A, B, _]) = {
implicit val hint = Shape.tuple2Shape(shape, shape)
q.map(x => (x, x))
}
// This fails. Why can't we find `tuple2Shape` in this case? FAILS IN SCALAC, WORKS IN DOTTY!
def pairItBad[A, B](q: Query[A, B])(implicit shape: Shape[_ <: FlatShapeLevel, A, B, _]) =
q.map(x => (x, x))
Scalac: https://scastie.scala-lang.org/2hFKFaBtSoiJuBDgt26vwA Dotty: https://scastie.scala-lang.org/TgdSZ64xS8e7Ta8HjzZyig
Scala-users thread: https://users.scala-lang.org/t/implicit-resolution-quirk/528/4
Any thoughts on this?
There are a lot of existential types in this example that make me feel uneasy (there's even a warning about them). Which naturally leads to the following definition that does work:
def pairItBad[L <: FlatShapeLevel, A, B, C](q: Query[A, B])(implicit shape: Shape[L, A, B, C]) =
q.map(x => (x, x))
Note: Dotty doesn't have existential types (only wildcards).
@joroKr21 Has this issue between existential types and implicit search been reported in scala/bug before?
I don't know. There are many issues about existential types. It's probably not so much the implicit search being involved, but rather type inference messing up with skolems and type variables.
Actually in this example implicit search does matter, because internally it uses an existential abstraction to find implicit candidates.