From a200695677237922fdf6f995c690cb0108ec2fc4 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 11 Jul 2016 14:02:38 +0200 Subject: Fix SI-2712 Allows partially instantiated types as type constrictors when inferring higher-kinded types. --- tests/neg/i94-nada.scala | 11 +++++++++++ tests/pickling/i94-nada.scala | 4 ++-- tests/pos/i94-nada.scala | 4 ++-- tests/pos/t2712-1.scala | 9 +++++++++ tests/pos/t2712-4.scala | 17 +++++++++++++++++ tests/pos/t2712-7.scala | 15 +++++++++++++++ tests/pos/t5683.scala | 23 +++++++++++++++++++++++ 7 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 tests/neg/i94-nada.scala create mode 100644 tests/pos/t2712-1.scala create mode 100644 tests/pos/t2712-4.scala create mode 100644 tests/pos/t2712-7.scala create mode 100644 tests/pos/t5683.scala (limited to 'tests') diff --git a/tests/neg/i94-nada.scala b/tests/neg/i94-nada.scala new file mode 100644 index 000000000..8ca104e06 --- /dev/null +++ b/tests/neg/i94-nada.scala @@ -0,0 +1,11 @@ +trait Test1 { + trait Monad[MX] { + def x: MX + } + sealed abstract class Either[A,B] + case class Left[A,B](x: A) extends Either[A,B] with Monad[A] + case class Right[A,B](x: B) extends Either[A,B] with Monad[B] + def flatMap[FX,FY,M[FMX]<:Monad[FMX]](m: M[FX], f: FX => M[FY]): M[FY] = f(m.x) + println(flatMap(Left(1), {x: Int => Left(x)})) // error: Left does not conform to [X] -> Monad[X] + +} diff --git a/tests/pickling/i94-nada.scala b/tests/pickling/i94-nada.scala index ce8dc98ad..cf39ee2ae 100644 --- a/tests/pickling/i94-nada.scala +++ b/tests/pickling/i94-nada.scala @@ -27,7 +27,7 @@ trait Test1 { case class Left[A,B](x: A) extends Either[A,B] with Monad[A] case class Right[A,B](x: B) extends Either[A,B] with Monad[B] def flatMap[X,Y,M[X]<:Monad[X]](m: M[X], f: X => M[Y]): M[Y] = f(m.x) - println(flatMap(Left(1), {x: Int => Left(x)})) + println(flatMap(Right(1), {x: Int => Right(x)})) } trait Test2 { trait Monad[X] { @@ -37,7 +37,7 @@ trait Test2 { case class Left[A,B](x: A) extends Either[A,B] with Monad[A] case class Right[A,B](x: B) extends Either[A,B] with Monad[B] def flatMap[X,Y,M[X]](m: M[X], f: X => M[Y]): M[Y] - println(flatMap(Left(1), {x: Int => Left(x)})) + println(flatMap(Right(1), {x: Int => Right(x)})) } trait Test3 { def flatMap[X,Y,M[X]](m: M[X], f: X => M[Y]): M[Y] diff --git a/tests/pos/i94-nada.scala b/tests/pos/i94-nada.scala index f8263ccf2..1c7d88a10 100644 --- a/tests/pos/i94-nada.scala +++ b/tests/pos/i94-nada.scala @@ -25,7 +25,7 @@ trait Test1 { case class Left[A,B](x: A) extends Either[A,B] with Monad[A] case class Right[A,B](x: B) extends Either[A,B] with Monad[B] def flatMap[X,Y,M[X]<:Monad[X]](m: M[X], f: X => M[Y]): M[Y] = f(m.x) - println(flatMap(Left(1), {x: Int => Left(x)})) + println(flatMap(Right(1), {x: Int => Right(x)})) } trait Test2 { trait Monad[X] { @@ -35,7 +35,7 @@ trait Test2 { case class Left[A,B](x: A) extends Either[A,B] with Monad[A] case class Right[A,B](x: B) extends Either[A,B] with Monad[B] def flatMap[X,Y,M[X]](m: M[X], f: X => M[Y]): M[Y] - println(flatMap(Left(1), {x: Int => Left(x)})) + println(flatMap(Right(1), {x: Int => Right(x)})) } trait Test3 { def flatMap[X,Y,M[X]](m: M[X], f: X => M[Y]): M[Y] diff --git a/tests/pos/t2712-1.scala b/tests/pos/t2712-1.scala new file mode 100644 index 000000000..4f84c9df5 --- /dev/null +++ b/tests/pos/t2712-1.scala @@ -0,0 +1,9 @@ +package test + +// Original test case from, +// +// https://issues.scala-lang.org/browse/SI-2712 +object Test { + def meh[M[_], A](x: M[A]): M[A] = x + meh{(x: Int) => x} // solves ?M = [X] Int => X and ?A = Int ... +} diff --git a/tests/pos/t2712-4.scala b/tests/pos/t2712-4.scala new file mode 100644 index 000000000..3e2e5cdda --- /dev/null +++ b/tests/pos/t2712-4.scala @@ -0,0 +1,17 @@ +package test + +object Test1 { + trait X + trait Y extends X + class Foo[T, U <: X] + def meh[M[_ <: A], A](x: M[A]): M[A] = x + meh(new Foo[Int, Y]) +} + +object Test2 { + trait X + trait Y extends X + class Foo[T, U >: Y] + def meh[M[_ >: A], A](x: M[A]): M[A] = x + meh(new Foo[Int, X]) +} diff --git a/tests/pos/t2712-7.scala b/tests/pos/t2712-7.scala new file mode 100644 index 000000000..d9c5243f1 --- /dev/null +++ b/tests/pos/t2712-7.scala @@ -0,0 +1,15 @@ +package test + +// Cats Xor, Scalaz \/, scala.util.Either +sealed abstract class Xor[+A, +B] extends Product with Serializable +object Xor { + final case class Left[+A](a: A) extends (A Xor Nothing) + final case class Right[+B](b: B) extends (Nothing Xor B) +} + +object TestXor { + import Xor._ + def meh[F[_], A, B](fa: F[A])(f: A => B): F[B] = ??? + meh(new Right(23): Xor[Boolean, Int])(_ < 13) + meh(new Left(true): Xor[Boolean, Int])(_ < 13) +} diff --git a/tests/pos/t5683.scala b/tests/pos/t5683.scala new file mode 100644 index 000000000..05ab03579 --- /dev/null +++ b/tests/pos/t5683.scala @@ -0,0 +1,23 @@ +object Test { + trait NT[X] + trait W[W, A] extends NT[Int] + type StringW[T] = W[String, T] + trait K[M[_], A, B] + + def k[M[_], B](f: Int => M[B]): K[M, Int, B] = null + + val okay1: K[StringW,Int,Int] = k{ (y: Int) => null: StringW[Int] } + val okay2 = k[StringW,Int]{ (y: Int) => null: W[String, Int] } + + val crash: K[StringW,Int,Int] = k{ (y: Int) => null: W[String, Int] } + + // remove `extends NT[Int]`, and the last line gives an inference error + // rather than a crash. + // test/files/pos/t5683.scala:12: error: no type parameters for method k: (f: Int => M[B])Test.K[M,Int,B] exist so that it can be applied to arguments (Int => Test.W[String,Int]) + // --- because --- + // argument expression's type is not compatible with formal parameter type; + // found : Int => Test.W[String,Int] + // required: Int => ?M[?B] + // val crash: K[StringW,Int,Int] = k{ (y: Int) => null: W[String, Int] } + // ^ +} -- cgit v1.2.3