Changing implicit variable from private to public cause 'covariant type T occurs in invariant position' Error

74 Views Asked by At

One of my class has a TypeTag:

abstract class Tagged[+T](implicit ttg: TypeTag[T])

the TypeTag (in this case a private variable) has caused some problem as its not serializable. So try to declare it as @transient:

abstract class Tagged[+T](@transient implicit val ttg: TypeTag[T])

But this seemingly trivial change has caused a big problem, Scala compiler throws the following error:

Error:(16, 51) covariant type T occurs in invariant position in type => org.apache.spark.sql.catalyst.ScalaReflection.universe.TypeTag[T] of value ttg
abstract class Tagged[+T](@transient implicit val ttg: TypeTag[T] = null) extends Extractor[T] with Static {
                                                  ^

What I did is just changing private variable to public. What should I do to eliminate such error?

1

There are 1 best solutions below

0
On

You did not "just change private variable to public". You changed a constructor parameter to a member variable. To see, why this is a problem, consider this:

  class Foo
  class Bar extends Foo


  val bar: Tagged[Foo]  = new Tagged[Bar](){}
  // The above is legal because T is covariant
  val foo = Tagged[Foo](bar.ttg)

The last line must also be legal, because bar is an instance of Tagged[Foo]. But, if this was possible, you'd end up with foo having a wrong TypeTag (one from Bar).