scala3
scala3 copied to clipboard
Incorrect inference of dependent types in classes
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.