I was playing around with some tricks with implicits and noticed that I got different behaviour than usual when a type related to java.io.Serializable is inferred (be it java.io.Serializable, scala.Serializable, Product with Serializable, ...). I'm not 100% sure whether this is caused by a bug, or if I'm just missing something.
I'm using the ambiguous implicits trick to have evidence of a certain implicit not being available:
sealed trait Not[A]
object Not {
implicit def makeNot[A]: Not[A] = new Not[A]{}
implicit def makeNotAmbig[A](implicit a: A): Not[A] = ???
}
Now I can do something like this:
scala> class Foo; class Bar
defined class Foo
defined class Bar
scala> def foo[T](s: Seq[T])(implicit ev: Not[AnyRef <:< T]) = s
foo: [T](s: Seq[T])(implicit ev: Not[<:<[AnyRef,T]])Seq[T]
scala> foo(List(new Foo, new Bar))
<console>:15: error: ambiguous implicit values:
both method makeNot in object Not of type [A]=> Not[A]
and method makeNotAmbig in object Not of type [A](implicit a: A)Not[A]
match expected type Not[<:<[AnyRef,Object]]
foo(List(new Foo, new Bar))
^
scala> foo(List(new Foo, new Foo))
res2: Seq[Foo] = List(Foo@713967dd, Foo@4e5adda7)
This seems to work pretty consistently until Serializable comes into play:
scala> def foo[T](s: Seq[T])(implicit ev: Not[java.io.Serializable <:< T]) = s
foo: [T](s: Seq[T])(implicit ev: Not[<:<[java.io.Serializable,T]])Seq[T]
scala> foo(List("string", Some(42)))
res3: Seq[java.io.Serializable] = List(string, Some(42))
scala> foo(List[java.io.Serializable]("string", Some(42)))
<console>:13: error: ambiguous implicit values:
both method makeNot in object Not of type [A]=> Not[A]
and method makeNotAmbig in object Not of type [A](implicit a: A)Not[A]
match expected type Not[<:<[java.io.Serializable,java.io.Serializable]]
foo(List[java.io.Serializable]("string", Some(42)))
^
Kind regards,
Jasper