Skip to content

Instantly share code, notes, and snippets.

@lukestephenson
Last active August 10, 2021 01:28
Show Gist options
  • Save lukestephenson/549c3c3c22733ae87bed9feafe9d0376 to your computer and use it in GitHub Desktop.
Save lukestephenson/549c3c3c22733ae87bed9feafe9d0376 to your computer and use it in GitHub Desktop.
Scala compiler error with dependant types
val scala3Version = "3.0.1"
lazy val root = project
.in(file("."))
.settings(
name := "scala3-simple",
version := "0.1.0",
scalaVersion := scala3Version,
libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test"
)
package luke
import scala.Tuple$package.EmptyTuple
import scala.compiletime._
import scala.compiletime.ops.int._
import scala.annotation.showAsInfix
type Bounded[MIN <: Int, MAX <: Int] <: Int = MAX match
case MIN => MIN
case ? => MAX | Bounded[MIN,MAX-1]
sealed trait TypedList[N <: Int]:
inline def size: N = valueOf[N]
def +:[H](h: H): TypedNonEmptyList[N, H, this.type] =
TypedNonEmptyList(h, this)
case object TypedNil extends TypedList[0]
case class TypedNonEmptyList[N <: Int, H, T <: TypedList[N]](head: H, tail: T) extends TypedList[S[N]]:
private def doDrop(t: TypedList[?], n: Int): TypedList[?] = {
if (n <= 0) t
else t match {
case TypedNil => TypedNil
case TypedNonEmptyList(_, tail)=> doDrop(tail, n - 1)
}
}
def drop(n: Bounded[0, S[N]]): Unit = {
this
}
object TypedExample {
def main(args: Array[String]): Unit = {
val tuple2 = 123 +: "abc" +: TypedNil
println(tuple2.tail.tail.size)
println(tuple2.size)
println(tuple2.drop(1))
println(tuple2.drop(2))
// This generates a nice compiler error as expected (if the val is uncommented)
// val test : Bounded[0, 2] = 3
// [error] 57 | val test : Bounded[0, 2] = 3
// [error] | ^
// [error] | Found: (3 : Int)
// [error] | Required: (2 : Int) | ((1 : Int) | (0 : Int))
// However the following call, which I'm hoping has the same Bounds causes the scala compiler to fail:
println(tuple2.drop(3))
// [info] exception occurred while compiling /Users/lstephenson/Code/zendesk/first-scala3/src/main/scala/luke/TypedList.scala
// java.lang.AssertionError: assertion failed: Attempt to commit TS[8610248X, 8609945X, 8609944, 8609822, 8609821, 8609820] into already committed TS[8609945X, 8609944, 8609822, 8609821, 8609820] while compiling /Users/lstephenson/Code/zendesk/first-scala3/src/main/scala/luke/TypedList.scala
// [error] ## Exception when compiling 2 sources to /Users/lstephenson/Code/zendesk/first-scala3/target/scala-3.0.1/classes
// [error] java.lang.AssertionError: assertion failed: Attempt to commit TS[8610248X, 8609945X, 8609944, 8609822, 8609821, 8609820] into already committed TS[8609945X, 8609944, 8609822, 8609821, 8609820]
// [error] scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
// [error] dotty.tools.dotc.core.TyperState.commit(TyperState.scala:146)
// [error] dotty.tools.dotc.typer.Inferencing$.isFullyDefined(Inferencing.scala:40)
// [error] dotty.tools.dotc.core.TypeOps$.simplify(TypeOps.scala:143)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment