Strange behaviour of inference/implicits when Serializable is involved

55 views
Skip to first unread message

Jasper-M

unread,
Nov 21, 2016, 9:28:03 AM11/21/16
to scala-internals
Hi,

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

Jasper-M

unread,
Nov 21, 2016, 9:47:24 AM11/21/16
to scala-internals
Apparently, this is not limited to Serializable. For instance Product and its subclasses also seem to have this.

Op maandag 21 november 2016 15:28:03 UTC+1 schreef Jasper-M:

Jasper-M

unread,
Nov 21, 2016, 10:10:40 AM11/21/16
to scala-internals
Excuse me for the spam, but you don't even have to look that far to see that something is not right:

scala> def foo[T](s: Seq[T])(implicit ev: java.io.Serializable <:< T): Seq[T] = s
foo: [T](s: Seq[T])(implicit ev: <:<[java.io.Serializable,T])Seq[T]

scala> foo(Seq("string", Some(42)))
<console>:16: error: Cannot prove that java.io.Serializable <:< java.io.Serializable.
       foo(Seq("string", Some(42)))
          ^


Op maandag 21 november 2016 15:47:24 UTC+1 schreef Jasper-M:
Reply all
Reply to author
Forward
0 new messages