bug icon indicating copy to clipboard operation
bug copied to clipboard

TypeTag of path-dependent type cannot be inferred by the compiler

Open tribbloid opened this issue 5 years ago • 7 comments
trafficstars

This problem has been recorded in:

https://stackoverflow.com/questions/59708880/in-scala-why-it-is-impossible-to-infer-typetag-from-type-alias-or-dependent-typ

A similar problem that may have the same cause has been reported in:

https://github.com/fthomas/singleton-ops/issues/152

reproduction steps

using Scala 2.13.3 OR 2.12.11,

object TTagFromPathDependentType {

  import universe._

  def infer(): Unit = {
    type U = (Int, String)

    val ttg1 = implicitly[TypeTag[(Int, String)]]

    val ttg2 = implicitly[TypeTag[U]]
  }
}

problem

Compiler throws the following error:

[Error] /home/peng/git/shapesafe/spike/src/main/scala/edu/umontreal/kotlingrad/spike/arity/TTagFromPathDependentType.scala:15: implicit error;
!I e (No TypeTag available for U): TypeTag[(Int,String)]
one error found

FAILURE: Build failed with an exception.

If the compiler is working properly it should have easily found the TypeTag for (Int, String)

tribbloid avatar Aug 12 '20 16:08 tribbloid

Related work https://github.com/scala/scala/pull/5836

Jasper-M avatar Aug 12 '20 18:08 Jasper-M

it appears to me that the problem is that the type isn't path-dependent, but rather is local to the block:

scala 2.13.3> object O { type U = (Int, String) }
object O

scala 2.13.3> implicitly[TypeTag[O.U]]
val res4: reflect.runtime.universe.TypeTag[O.U] = TypeTag[O.U]

scala 2.13.3> { type U = (Int, String); implicitly[TypeTag[U]] }
                                                  ^
              error: No TypeTag available for U

SethTisue avatar Nov 11 '20 21:11 SethTisue

@SethTisue The problem is with "free" types, of which local types are an example. But also path dependent types whose definition is not statically accessible (for lack of a better specification):

val a = new { type T = Int }
typeOf[a.T]

trait Foo { type T }
val foo = new Foo { type T = Int }
typeOf[foo.T]

Jasper-M avatar Nov 11 '20 21:11 Jasper-M

@Jasper-M are you saying that once I moved those definition into a class or an object instead of a function the error will disappear?

tribbloid avatar Dec 14 '20 21:12 tribbloid

are you saying that once I moved those definition into a class or an object instead of a function the error will disappear?

If you move the type for which you want a TypeTag out of the function it should work yes.

Jasper-M avatar Dec 14 '20 21:12 Jasper-M

I'm wondering if we should just close this, on the grounds that it's an understandable and reasonable limitation, rather than a bug or shortcoming.

(At least, that's what I think about the case where the path in the path-dependent type is local. Less sure what I think about Jasper's case.)

SethTisue avatar Apr 21 '22 18:04 SethTisue

Yes I agree it is a free type, but it is also a type alias that can be immediately de-aliased to a dependent type.

Theoretically this is not a variable binding, so no guarantee for type equivalence, but developers may still perceive it that way

tribbloid avatar Apr 21 '22 18:04 tribbloid