scala / bug

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

polymorphic expression cannot be instantiated to expected type #8983

Open scabug opened 9 years ago

scabug commented 9 years ago

Type inference fails if an expression is directly assigned to a value but succeeds if the very same expression is first assigned to an intermediary value and then to the actual value.

Comment to grasp the example code more quickly

The idea is to enable parser combinators to work with Shapeless HLists. An ordinary Parser[O] can be lifted into a Parser[O :: HNil]. Parsers are augmented with an "::" operation that allows to join two Parsers. The HListParser typeclass allows the join operation to work uniformly irrespective of where a parser works on HLists or not.

Example Code

object Test {

  import shapeless._
  import shapeless.ops.hlist.Prepend

  trait Parser[O] {
    def map[X](f: O => X): Parser[X]
    def flatMap[X](f: O => Parser[X]): Parser[X]
  }

  trait HListParser[IN, OUT <: HList] {
    def apply(p: Parser[IN]): Parser[OUT]
  }

  trait LowPrio {
    // lift an arbitrary parser into a parser that returns an HList
    implicit def lift[O] = new HListParser[O, O :: HNil] {
      override def apply(p: Parser[O]): Parser[O :: HNil] = p map (_ :: HNil)
    }
  }

  object HListParser extends LowPrio {
    implicit def noop[O <: HList] = new HListParser[O, O] {
      override def apply(p: Parser[O]): Parser[O] = p
    }
  }

  object Parser {

    implicit class ParserOps[O1, O1HL <: HList](val p1: Parser[O1])(implicit val ev1: HListParser[O1, O1HL]) {
      // join 2 parsers; returns a parser that returns
      def ::[O2, O2HL <: HList](p2: Parser[O2])(implicit ev2: HListParser[O2, O2HL], prep: Prepend[O2HL, O1HL]): Parser[prep.Out] = for {
        v2 <- ev2(p2)
        v1 <- ev1(p1)
      } yield prep(v2, v1)

    }
  }

  val a: Parser[Int] = null
  val b: Parser[String] = null

  val err: Parser[Int :: String :: HNil] = a :: b

//  Error:(46, 46) polymorphic expression cannot be instantiated to expected type;
//  found   : [O2HL <: shapeless.HList]Test.Parser[prep.Out]
//  required: Test.Parser[shapeless.::[Int,shapeless.::[String,shapeless.HNil]]]

  val ok: Parser[Int :: String :: HNil] = {
    val p = a :: b
    p
  }

}
scabug commented 9 years ago

Imported From: https://issues.scala-lang.org/browse/SI-8983?orig=1 Reporter: stefan.wachter-at-gmx.de Affected Versions: 2.11.4

Jasper-M commented 6 years ago

Correct me if I'm wrong, but I think this is a more self contained example of more or less the same problem:

val ok: Iterable[Boolean] = {
  val a = Option(Option(true)).flatten
  a
}

val err: Iterable[Boolean] = Option(Option(true)).flatten //error: polymorphic expression cannot be instantiated to expected type

(works in dotty)