Scala Programming Language
  1. Scala Programming Language
  2. SI-6472

Type inference forgets to process some type parameters

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: Scala 2.9.2, Scala 2.10.0-M7, Scala 2.10.0
    • Fix Version/s: None
    • Labels:
      None

      Description

      Given an environment where T is not bound to some type, I can get this error message:

        Foo.scala:21: error: type mismatch;
         found   : Foo.Exp[Seq[T]]
         required: Foo.Exp[Seq[Nothing]]
          assertType[Exp[Seq[Nothing]]](v)
                                        ^
      

      where the T in the output message is an uninferred type parameter!

      The core of the offending code is:

        val empty = Const(Seq.empty)
        //...Implicit conversions to pimp map and head on Const[Seq[T]]...
        val v = empty.map(x => empty.head)
        //Not fine:
        assertType[Exp[Seq[Nothing]]](v)
      

      See https://gist.github.com/3830228 for the complete code (I can attach it here if important).

      As a consequence, in 2.10 that expression cannot be passed to this function:

      def f[T: TypeTag](e: Exp[T]): T = throw new Exception()
      f(empty.map(x => empty.head))
      /*
      Error:
      Foo.scala:38: error: type parameter not specified
        f(empty.map(x => empty.head))
         ^
      

        Activity

        Hide
        Paul Phillips added a comment -

        Considerably reduced. The difference between g0 and g1 below is only whether the implicit conversion is called explicitly.

        object Bar {
          implicit def convert[T](xs: Seq[T]) = new Bippy(xs)
          class Bippy[T](xs: Seq[T]) { def bippy = xs }
        
          def g0 = identity(Seq().bippy)
          def g1 = identity(convert(Seq()).bippy)
          // def g0: Seq[T] = ...
          // def g1: Seq[Nothing] = ...
        }
        
        Show
        Paul Phillips added a comment - Considerably reduced. The difference between g0 and g1 below is only whether the implicit conversion is called explicitly. object Bar { implicit def convert[T](xs: Seq[T]) = new Bippy(xs) class Bippy[T](xs: Seq[T]) { def bippy = xs } def g0 = identity(Seq().bippy) def g1 = identity(convert(Seq()).bippy) // def g0: Seq[T] = ... // def g1: Seq[Nothing] = ... }

          People

          • Assignee:
            Unassigned
            Reporter:
            Paolo G. Giarrusso
          • Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

            • Created:
              Updated:

              Development