summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2015-06-30 13:48:56 -0700
committerAdriaan Moors <adriaan.moors@typesafe.com>2015-06-30 13:48:56 -0700
commitc8fbc41631da0a860f749479a610312814c0e88f (patch)
tree4c9b6759469530454b95b3fd2ac600e1042941da /test
parent6ca8847eb5891fa610136c2c041cbad1298fb89c (diff)
parent4a61719c1a3b57b47aa65409e83b87cff39145d3 (diff)
downloadscala-c8fbc41631da0a860f749479a610312814c0e88f.tar.gz
scala-c8fbc41631da0a860f749479a610312814c0e88f.tar.bz2
scala-c8fbc41631da0a860f749479a610312814c0e88f.zip
Merge pull request #4569 from retronym/ticket/6985
SI-6895 Test cases to explain the limitations in tcpoly inference
Diffstat (limited to 'test')
-rw-r--r--test/files/neg/t6895.check6
-rw-r--r--test/files/neg/t6895.scala26
-rw-r--r--test/files/neg/t6895b.check9
-rw-r--r--test/files/neg/t6895b.scala39
-rw-r--r--test/files/neg/t8777.check6
-rw-r--r--test/files/neg/t8777.scala4
-rw-r--r--test/files/neg/t8892.check7
-rw-r--r--test/files/neg/t8892.scala2
8 files changed, 99 insertions, 0 deletions
diff --git a/test/files/neg/t6895.check b/test/files/neg/t6895.check
new file mode 100644
index 0000000000..df01031fff
--- /dev/null
+++ b/test/files/neg/t6895.check
@@ -0,0 +1,6 @@
+t6895.scala:19: error: polymorphic expression cannot be instantiated to expected type;
+ found : [F3[F3_P]]Foo[F3]
+ required: Foo[[X3]Bar[[X1]String]]
+ val nok: Foo[({type L[X3] = Bar[M]})#L] = barFoo /* Type inference can't unify F with L */
+ ^
+one error found
diff --git a/test/files/neg/t6895.scala b/test/files/neg/t6895.scala
new file mode 100644
index 0000000000..5fb20d8c61
--- /dev/null
+++ b/test/files/neg/t6895.scala
@@ -0,0 +1,26 @@
+trait Foo[F1[F1_P]]
+trait Bar[F2[F2_P]]
+
+class Test {
+ def barFoo[F3[F3_P]]: Foo[F3] = ???
+
+ // Now we can define a couple of type aliases:
+ type M[X1] = String
+ type N[X2] = Bar[M]
+
+ // val ok1: Foo[N] = barFoo
+ // Foo[?F3] <:< Foo[Test.this.N]
+ // [X2]Test.this.N[X2] <:< [F3_P]?F3[F3_P]
+ // Test.this.N[X2] <:< ?F3[X2]
+ // true, ?F3=N
+
+ // val ok2: Foo[({type L[X] = Bar[M]})#L] = barFoo[N]
+
+ val nok: Foo[({type L[X3] = Bar[M]})#L] = barFoo /* Type inference can't unify F with L */
+ // Foo[?F3] <:< Foo[[X3]Bar[[X1]String]]
+ // [X3]Bar[[X1]String] <:< ?F3
+ // [X3]Bar[[X1]String] <:< [F3_P]?F3[F3_P]
+ // Bar[[X1]String] <:< ?F3[X3]
+ // X3 <:< [X1]String
+ // false
+}
diff --git a/test/files/neg/t6895b.check b/test/files/neg/t6895b.check
new file mode 100644
index 0000000000..565925127b
--- /dev/null
+++ b/test/files/neg/t6895b.check
@@ -0,0 +1,9 @@
+t6895b.scala:20: error: could not find implicit value for parameter e: Foo[[X]Bar[[X]Or[String,X],X]]
+ implicitly[Foo[({type L[X] = Bar[StringOr, X]})#L]]
+ ^
+t6895b.scala:23: error: polymorphic expression cannot be instantiated to expected type;
+ found : [F[_]]Foo[[X(in type L)]Bar[F,X(in type L)]]
+ required: Foo[[X(in type L)]Bar[[X]Or[String,X],X(in type L)]]
+ barFoo(null) : Foo[({type L[X] = Bar[StringOr, X]})#L]
+ ^
+two errors found
diff --git a/test/files/neg/t6895b.scala b/test/files/neg/t6895b.scala
new file mode 100644
index 0000000000..c465065011
--- /dev/null
+++ b/test/files/neg/t6895b.scala
@@ -0,0 +1,39 @@
+trait Foo[F[_]]
+trait Bar[F[_], A]
+
+trait Or[A, B]
+
+class Test {
+ implicit def orFoo[A]: Foo[({type L[X] = Or[A, X]})#L] = ???
+ implicit def barFoo[F[_]](implicit f: Foo[F]): Foo[({type L[X] = Bar[F, X]})#L] = ???
+
+ // Now we can define a couple of type aliases:
+ type StringOr[X] = Or[String, X]
+ type BarStringOr[X] = Bar[StringOr, X]
+
+ // ok
+ implicitly[Foo[BarStringOr]]
+ barFoo[StringOr](null) : Foo[BarStringOr]
+ barFoo(null) : Foo[BarStringOr]
+
+ // nok
+ implicitly[Foo[({type L[X] = Bar[StringOr, X]})#L]]
+ // Let's write the application explicitly, and then
+ // compile with just this line enabled and -explaintypes.
+ barFoo(null) : Foo[({type L[X] = Bar[StringOr, X]})#L]
+
+ // Foo[[X]Bar[F,X]] <: Foo[[X]Bar[[X]Or[String,X],X]]?
+ // Bar[[X]Or[String,X],X] <: Bar[F,X]?
+ // F[_] <: Or[String,_]?
+ // false
+ // false
+ // false
+
+ // Note that the type annotation above is typechecked as
+ // Foo[[X]Bar[[X]Or[String,X],X]], ie the type alias `L`
+ // is eta expanded.
+ //
+ // This is done so that it does not escape its defining scope.
+ // However, one this is done, higher kinded inference
+ // no longer is able to unify F with `StringOr` (SI-2712)
+}
diff --git a/test/files/neg/t8777.check b/test/files/neg/t8777.check
new file mode 100644
index 0000000000..cd05f1ec11
--- /dev/null
+++ b/test/files/neg/t8777.check
@@ -0,0 +1,6 @@
+t8777.scala:3: error: type mismatch;
+ found : Foo.this.TreePrinter(in trait Printers)
+ required: Foo.this.TreePrinter(in trait Printers)
+ super.newCodePrinter(out, tree, printRootPkg)
+ ^
+one error found
diff --git a/test/files/neg/t8777.scala b/test/files/neg/t8777.scala
new file mode 100644
index 0000000000..5b7d123202
--- /dev/null
+++ b/test/files/neg/t8777.scala
@@ -0,0 +1,4 @@
+trait Foo extends scala.tools.nsc.Global {
+ override def newCodePrinter(out: java.io.PrintWriter, tree: Tree, printRootPkg: Boolean): TreePrinter =
+ super.newCodePrinter(out, tree, printRootPkg)
+}
diff --git a/test/files/neg/t8892.check b/test/files/neg/t8892.check
new file mode 100644
index 0000000000..5930be58c5
--- /dev/null
+++ b/test/files/neg/t8892.check
@@ -0,0 +1,7 @@
+t8892.scala:2: error: type mismatch;
+ found : B
+ required: C.this.B
+ (which expands to) String
+class C[B](x: B) extends A { def f: B = x }
+ ^
+one error found
diff --git a/test/files/neg/t8892.scala b/test/files/neg/t8892.scala
new file mode 100644
index 0000000000..f857e6f115
--- /dev/null
+++ b/test/files/neg/t8892.scala
@@ -0,0 +1,2 @@
+trait A { type B = String }
+class C[B](x: B) extends A { def f: B = x }