From 0e306e1f90f51efa2d423fd7df810f7cc8dfa915 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sun, 19 Dec 2010 23:20:13 +0000 Subject: Explaining something for the (largeish N)th tim... Explaining something for the (largeish N)th time finally awoke me to the fact that software can explain things. I labored a long time over this error message: I'm sure it can still use work (and/or it will drive scalaz users off some kind of cliff) but the simple common case people have so much trouble with is lit up like a christmas tree and for this I will take some bullets. build/pack/bin/scala -e 'class Foo[T] ; Set[Foo[AnyRef]]() + new Foo[String]' :1: error: type mismatch; found : this.Foo[String] required: this.Foo[java.lang.Object] Note: String <: java.lang.Object, but class Foo is invariant in type T. You may wish to define T as +T instead. (SLS 4.5) class Foo[T] ; Set[Foo[AnyRef]]() + new Foo[String] ^ Review by moors. --- test/files/neg/found-req-variance.scala | 106 ++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 test/files/neg/found-req-variance.scala (limited to 'test/files/neg/found-req-variance.scala') diff --git a/test/files/neg/found-req-variance.scala b/test/files/neg/found-req-variance.scala new file mode 100644 index 0000000000..c44d021fac --- /dev/null +++ b/test/files/neg/found-req-variance.scala @@ -0,0 +1,106 @@ +import scala.collection.mutable.ListBuffer + +class A +class B extends A +class C extends B + +trait FF1[T, +R] +trait FF2[-T, R] + +class Inv[T] +class InvA extends Inv[A] +class InvB extends Inv[B] +class InvC extends Inv[C] + +class Multi[+Cov, Inv, -Con] +class MultiCov[+T <: A] extends Multi[T, B, C] +class MultiInv[T] extends Multi[A, T, C] +class MultiCon[-T >: C] extends Multi[A, B, T] + +object Test { + def f1 = Set[Inv[A]]() + new Inv[A] + def f2 = Set[Inv[A]]() + new Inv[B] + def f3 = Set[Inv[A]]() + new Inv[C] + def f4 = Set[Inv[B]]() + new Inv[A] + def f5 = Set[Inv[B]]() + new Inv[B] + def f6 = Set[Inv[B]]() + new Inv[C] + def f7 = Set[Inv[C]]() + new Inv[A] + def f8 = Set[Inv[C]]() + new Inv[B] + def f9 = Set[Inv[C]]() + new Inv[C] + + def g1 = Set[Multi[A, B, C]]() + new MultiCov[A] + def g2 = Set[Multi[A, B, C]]() + new MultiCov[B] + def g3 = Set[Multi[A, B, C]]() + new MultiCov[C] + def g4 = Set[Multi[A, B, C]]() + new MultiInv[A] + def g5 = Set[Multi[A, B, C]]() + new MultiInv[B] + def g6 = Set[Multi[A, B, C]]() + new MultiInv[C] + def g7 = Set[Multi[A, B, C]]() + new MultiCon[A] + def g8 = Set[Multi[A, B, C]]() + new MultiCon[B] + def g9 = Set[Multi[A, B, C]]() + new MultiCon[C] +} + +object Functions { + object Set1 { + def f[T, R](x: FF1[T, R]) = () + def h[T, R] : FF1[T, R] = system.error("") + + def ff1 = f[B, B](h[A, A]) // fail + def ff2 = f[B, B](h[B, A]) // fail + def ff3 = f[B, B](h[C, A]) // fail + def ff4 = f[B, B](h[A, B]) // suggest + def ff5 = f[B, B](h[B, B]) // ok + def ff6 = f[B, B](h[C, B]) // suggest + def ff7 = f[B, B](h[A, C]) // suggest + def ff8 = f[B, B](h[B, C]) // ok + def ff9 = f[B, B](h[C, C]) // suggest + } + object Set2 { + def f[T, R](x: FF2[T, R]) = () + def h[T, R] : FF2[T, R] = system.error("") + + def ff1 = f[B, B](h[A, A]) // suggest + def ff2 = f[B, B](h[B, A]) // suggest + def ff3 = f[B, B](h[C, A]) // fail + def ff4 = f[B, B](h[A, B]) // ok + def ff5 = f[B, B](h[B, B]) // ok + def ff6 = f[B, B](h[C, B]) // fail + def ff7 = f[B, B](h[A, C]) // suggest + def ff8 = f[B, B](h[B, C]) // suggest + def ff9 = f[B, B](h[C, C]) // fail + } +} + +// TODO +// object TypeAlias { +// type LL[T] = List[T] +// val LL = List +// +// def f1 = Set[LL[B]]() + LL[A](new A) +// def f2 = Set[LL[B]]() + LL[C](new C) +// } + +object Javas { + def f[T](x: java.util.List[T]) = () + def g[T](x: java.util.Comparator[T]) = () + + def g1 = f[AnyRef](new java.util.ArrayList[String] { }) + def g2 = g[String](Ordering.fromLessThan[AnyRef](_.toString < _.toString)) +} + +object Misc { + // original motivation + class Data[A <: AnyVal] + class MyData extends Data[Int] { } + def f1 = Set[Data[AnyVal]]() + new MyData + + // from stackoverflow + def foo(s: Set[CharSequence]): Unit = () + def f4 = { + val s: Set[String] = Set("Hello", "World"); + foo(s) + } + + class Trippy[+T1, T2, +T3] + def g1 = Set[Trippy[AnyRef, AnyRef, AnyRef]]() + new Trippy[String, String, String] + def g2 = Set[Map[String, String]]() + Map[AnyRef, String]() +} \ No newline at end of file -- cgit v1.2.3