scala3 icon indicating copy to clipboard operation
scala3 copied to clipboard

Incorrect inference of dependent types in classes

Open jchyb opened this issue 3 years ago • 0 comments

Inspired by the shapeless-2 codebase, as I was looking what still remains to be done there and run into problems with type-level natural numbers implementation there.

Compiler version

3.2.1-RC1-bin-20220805-e560c2d-NIGHTLY, previous stable versions as well

Minimized code

//> using scala "3.nightly"

trait Nat { type N <: Nat }

class _0 extends Nat {
  type N = _0  // source of our issues 
}

class NatOps[N <: Nat](val n: N) {
  // does not work, ToInt[n.N] becomes Nothing
  def toInt(implicit toIntN: ToInt[n.N]): Int = toIntN()
}

// works
def toInt[N <: Nat](n: N)(implicit toIntN: ToInt[n.N]) = toIntN()

sealed abstract class ToInt[N <: Nat] {
  def apply(): Int
}

object ToInt {
  implicit val toInt0: ToInt[_0] = new ToInt {
    def apply(): Int = 0
  }
}

@main def main() =
  println(toInt(new _0)) // works
  println(NatOps(new _0).toInt) // does not work, but NatOps[_0](new _0).toInt works

Output

[error] ./ShapelessNatBug.scala:28:31: No given instance of type Nothing was found for parameter toIntN of method toInt in class NatOps
[error]   println(NatOps(new _0).toInt) // does not work, but NatOps[_0](new _0).toInt works
[error]       

Expectation

Should compile and print "0", like the method version (def toInt) does. Very similar to #10929, but here the dependent types aren't part of the type classes, ToInt[n.N] simply cannot be found because of inference caused by constructor of a class, which I hope makes for a simpler minimization. If the issues are indeed more similar than I though I can move this post there.

jchyb avatar Aug 10 '22 08:08 jchyb