scalatags
scalatags copied to clipboard
Example doesn't work in Scala 3 with latest versions and sbt
Hi there - I copied your example from cask/scalatags but used the latest versions and Scala 3 and I'm getting a spurious error:
Found: scalatags.Text.all.html.Self
Required: scalatags.text.Frag
The following import might make progress towards fixing the problem:
import sourcecode.Text.generate
html(
build.sbt:
val scala3Version = "3.1.0"
lazy val root = project
.in(file("."))
.settings(
name := "Pride and Joy",
version := "0.1.0-SNAPSHOT",
scalaVersion := scala3Version,
libraryDependencies += "com.lihaoyi" % "cask_3" % "0.8.0",
libraryDependencies += "com.lihaoyi" % "requests_3" % "0.7.0",
libraryDependencies += "com.lihaoyi" % "scalatags_3" % "0.11.0",
libraryDependencies += "com.lihaoyi" % "utest_3" % "0.7.10" % "test",
libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test",
)
src/main/scala/Main:
//package app
import scalatags.Text.all._
object Main extends cask.MainRoutes{
@cask.get("/")
def hello() = {
doctype("html")(
html(
body(
h1("Hello World"),
p("I am cow")
)
)
)
}
initialize()
}
Is this something obvious, or should I stick with the older versions used in the demo?
Thanks!
I have also encountered this problem and it seems to be a regression in scalatags because it works fine on 2.13.x versions but not on 3.x.x versions. It seems that the protected[this] qualifier is no longer permitted in Scala 3 which might be related to this problem. From my admittedly limited time of debugging, the Self type inside scalatags.Text.TypedTag has issues with variance which is getting ignored by the @uncheckedVariance annotation. For Scala 2, the scalatags.text.TagFactory#tag function used to create tags such as html, a and so forth refines to ConcreteHtmlTag[String] but in Scala 3, it refines into <tag-name>.Self where <tag-name> is the name of a tag like html or a. This results in the type checking error that you have seen where Self cannot be resolved to text.Frag.
Since doctype is only present in the text packages, I do not think that this issue occurs in the js-dom packages however everything else related to variance most likely does...but I am not fully sure. Here is a slightly smaller reproducible example using mill as the build tool:
build.sc
import mill._
import mill.scalalib._
object example extends ScalaModule {
// Replace this with Scala 2 or Scala 3 to view the difference.
override def scalaVersion = "3.0.2"
override def scalacOptions = T {
super.scalacOptions() ++
if (isScala3(scalaVersion)) {
Seq("-explain")
} else {
Seq()
}
}
override def ivyDeps = T {
super.ivyDeps() ++ Agg(
ivy"com.lihaoyi::scalatags:0.11.0"
)
}
}
example/src/Example.scala
package example
import scalatags.Text.all._
object Example {
def main(args: Array[String]): Unit =
println("hello world")
// Fails in Scala 3.
def example() =
doctype("html")(
html()
)
}
(nice reduction and investigation - thanks)
Could you work around it by using asInstanceOf?
@edwardcwang sorry for the late reply but from what I remember, asInstanceOf worked in some places but it does not work as general solution. I only managed to realise that annotating the types explicitly worked because of some trial and error.