scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
232 stars 21 forks source link

High Order Type cannot be inferred properly #12177

Open neontorrent opened 4 years ago

neontorrent commented 4 years ago

reproduction steps

using Scala 2.13.x,

scala> case class Foo[CC[_]](a: CC[Int], b: CC[Int])
class Foo

scala> trait Conv[T] { def apply(a: T): Foo[collection.Seq] }
trait Conv

scala> implicit val ConsBConv: Conv[Int] = a => Foo(scala.collection.mutable.ListBuffer(a), Nil)
                                                ^
       error: no type parameters for method apply: (a: CC[Int], b: CC[Int]): Foo[CC] in object Foo exist so that it can be applied to arguments (scala.collection.mutable.ListBuffer[Int], scala.collection.immutable.Nil.type)
        --- because ---
       argument expression's type is not compatible with formal parameter type;
        found   : scala.collection.immutable.Nil.type
        required: ?CC[Int]
                                                                                       ^
       error: type mismatch;
        found   : scala.collection.mutable.ListBuffer[Int]
        required: CC[Int]
                                                                                            ^
       error: type mismatch;
        found   : scala.collection.immutable.Nil.type
        required: CC[Int]
                                                   ^
       error: type mismatch;
        found   : Foo[CC]
        required: Foo[scala.collection.Seq]

scala> implicit val ConsBConv: Conv[Int] = a => Foo[collection.Seq](scala.collection.mutable.ListBuffer(a), Nil)
val ConsBConv: Conv[Int] = $anonfun$1@e2498a3

scala> implicit val ConsBConv: Conv[Int] = a => Foo(scala.collection.mutable.ListBuffer(a), scala.collection.mutable.ListBuffer.empty)
                                                ^
       error: no type parameters for method apply: (a: CC[Int], b: CC[Int]): Foo[CC] in object Foo exist so that it can be applied to arguments (scala.collection.mutable.ListBuffer[Int], scala.collection.mutable.ListBuffer[Nothing])
        --- because ---
       argument expression's type is not compatible with formal parameter type;
        found   : scala.collection.mutable.ListBuffer[Nothing]
        required: ?CC[Int]
                                                                                       ^
       error: type mismatch;
        found   : scala.collection.mutable.ListBuffer[Int]
        required: CC[Int]
                                                                                                                                ^
       error: type mismatch;
        found   : scala.collection.mutable.ListBuffer[Nothing]
        required: CC[Int]
                                                   ^
       error: type mismatch;
        found   : Foo[CC]
        required: Foo[scala.collection.Seq]

scala> implicit val ConsBConv: Conv[Int] = a => Foo(scala.collection.mutable.ListBuffer(a), scala.collection.mutable.ListBuffer.empty[Int])
val ConsBConv: Conv[Int] = $anonfun$1@6dae5562

problem

When a return value of SAM method contains a high order type in the class to be deduced, Scala cannot seem to deduce it properly, unless the high order type is explicitly specified.

Scala compiler should be able to deduce the type argument since the SAM trait already explicitly defined the full return type


EDIT

It turns out not related to SAM, because the following also fails:

scala> case class Foo[+CC[_]](a: CC[Int], b: CC[Int])
class Foo

scala> Foo(scala.collection.mutable.ListBuffer(1), scala.collection.mutable.ListBuffer.empty)
       ^
       error: no type parameters for method apply: (a: CC[Int], b: CC[Int]): Foo[CC] in object Foo exist so that it can be applied to arguments (scala.collection.mutable.ListBuffer[Int], scala.collection.mutable.ListBuffer[Nothing])
        --- because ---
       argument expression's type is not compatible with formal parameter type;
        found   : scala.collection.mutable.ListBuffer[Nothing]
        required: ?CC[Int]
                                              ^
       error: type mismatch;
        found   : scala.collection.mutable.ListBuffer[Int]
        required: CC[Int]
                                                                                       ^
       error: type mismatch;
        found   : scala.collection.mutable.ListBuffer[Nothing]
        required: CC[Int]
          ^
       error: type mismatch;
        found   : Foo[CC]
        required: Foo[scala.collection.Seq]

scala> Foo(scala.collection.mutable.ListBuffer(1), scala.collection.mutable.ListBuffer.empty[Int])
val res1: Foo[scala.collection.mutable.ListBuffer] = Foo(ListBuffer(1),ListBuffer())
SethTisue commented 3 years ago

To further minimize: it's irrelevant that it's a case class.

Dotty (0.27.0-RC1) 💪s it:

scala> case class Foo[+CC[_]](a: CC[Int], b: CC[Int])                                                                   
// defined case class Foo

scala> Foo(scala.collection.mutable.ListBuffer(1), scala.collection.mutable.ListBuffer.empty)                           
val res0: Foo[scala.collection.mutable.ListBuffer] = Foo(ListBuffer(1),ListBuffer())
Jasper-M commented 3 years ago

Related to #10428?