1

Use case: I'm writing tests for a Scala 3 program using scalatest. I want to print a meaningful fail message saying that the expected parameterized type did not equal the found parameterized type.

eg:

Expected: scala.util.Failure[ IllegalArgumentException ]
Found: scala.util.Failure[ NotImplementedException ]

In Scala 2.13, I would use sbt to add a library dependency on "org.scala-lang" % "scala-reflect" % scalaVersion.value, which would allow me to import the package scala.reflect.runtime.universe and do something like this:

import org.scalatest.funspec.AnyFunSpec
import scala.reflect.runtime.universe
import scala.util.Failure

class ExampleSpec extends AnyFunSpec {

  def getTypeTag[ T : universe.TypeTag ]( obj : T ) = universe.typeTag[ T ]

  describe( "rejectEmptyStrings( textInput : String ) : Try[ Any ]" ) {

    it( "Rejects empty strings." ) {
      
      rejectEmptyStrings( "" ) match {
        case Failure( _ : IllegalArgumentException ) => succeed
        case other => fail(
          "Expected: scala.util.Failure[ IllegalArgumentException ]\n" +
            s"Found: ${ getTypeTag( other ).tpe }"
        )
      }
    }
  }
}

(The getTypeTag function is provided by this page of the docs.)

But how would I do the same thing in Scala 3?

There does not seem to be a scala-reflect package for Scala 3. Can I use the Scala 2.13 version with a cross-version dependency?

libraryDependencies += ( "org.scala-lang" % "scala-reflect" % scalaVersion.value )
  .cross( CrossVersion.for3Use2_13 )

At time of writing, all of the current docs about reflection focus on metaprogramming and macros. (Not my use case.) They make no reference to TypeTags and how to access them.

And, of course, if there is a simpler solution to my use case that I'm not seeing - one that does not rely on reflection - I am open to it.

Leo Orientis
  • 841
  • 11
  • 19
  • 5
    Currently `TypeTag` is removed from scala 3.0 (an in general the old runtime reflection, a discussion started [here](https://contributors.scala-lang.org/t/scala-3-and-reflection/3627)). TypeTag is unsafe because expose internal compiler constructs. Some third-party library tries to port TypeTag in scala 3.0 as [this](https://github.com/zio/izumi-reflect) and [this](https://github.com/gzoller/scala-reflection) – gianluca aguzzi May 24 '21 at 15:17
  • 3
    You cannot and should not use scala-reflect in Scala 3. – Gaël J May 24 '21 at 18:34
  • 1
    If you are just pattern matching on a `Try` and interested in the exception class, you don't even need the whole `TypeTag` in Scala 2. I guess you are dealing with more complexe cases, if so may you share one? – Gaël J May 24 '21 at 18:36
  • @GaëlJ, The point is to be able to print the value of the found parameterized type in error messages. I've been reading about the topic and realize it is more complex... The sbt console and compiler can print the compile-time type. `scala.reflect.runtime.universe` used to be able to represent the runtime type, but I think this was found to be insecure, and it was discontinued in Scala 3. What remains: Is there a way to make an error message that tells users of my compiled jar library the type that was expected, and the type of the object they provided? – Leo Orientis May 24 '21 at 21:42

0 Answers0