Skip to content

Implicit resolution bug in scalac (working in dotty) #10420

Open
@virusdave

Description

@virusdave

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions