Last active
August 10, 2021 01:28
-
-
Save lukestephenson/549c3c3c22733ae87bed9feafe9d0376 to your computer and use it in GitHub Desktop.
Scala compiler error with dependant types
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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