Skip to content

Commit a24fe19

Browse files
committed
Fix for SI-9363
1 parent 543ebf6 commit a24fe19

File tree

2 files changed

+40
-5
lines changed

2 files changed

+40
-5
lines changed

src/library/scala/PartialFunction.scala

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ package scala
2020
* {{{
2121
* val f: PartialFunction[Int, Any] = { case _ => 1/0 }
2222
* }}}
23-
*
23+
*
2424
* It is the responsibility of the caller to call `isDefinedAt` before
2525
* calling `apply`, because if `isDefinedAt` is false, it is not guaranteed
2626
* `apply` will throw an exception to indicate an error condition. If an
@@ -161,7 +161,8 @@ trait PartialFunction[-A, +B] extends (A => B) { self =>
161161
object PartialFunction {
162162
/** Composite function produced by `PartialFunction#orElse` method
163163
*/
164-
private class OrElse[-A, +B] (f1: PartialFunction[A, B], f2: PartialFunction[A, B]) extends scala.runtime.AbstractPartialFunction[A, B] {
164+
private class OrElse[-A, +B] (f1: PartialFunction[A, B], f2: PartialFunction[A, B])
165+
extends scala.runtime.AbstractPartialFunction[A, B] with Serializable {
165166
def isDefinedAt(x: A) = f1.isDefinedAt(x) || f2.isDefinedAt(x)
166167

167168
override def apply(x: A): B = f1.applyOrElse(x, f2)
@@ -180,7 +181,7 @@ object PartialFunction {
180181

181182
/** Composite function produced by `PartialFunction#andThen` method
182183
*/
183-
private class AndThen[-A, B, +C] (pf: PartialFunction[A, B], k: B => C) extends PartialFunction[A, C] {
184+
private class AndThen[-A, B, +C] (pf: PartialFunction[A, B], k: B => C) extends PartialFunction[A, C] with Serializable {
184185
def isDefinedAt(x: A) = pf.isDefinedAt(x)
185186

186187
def apply(x: A): C = k(pf(x))
@@ -217,15 +218,15 @@ object PartialFunction {
217218
private def fallbackOccurred[B](x: B) = (fallback_pf eq x.asInstanceOf[AnyRef])
218219

219220
private class Lifted[-A, +B] (val pf: PartialFunction[A, B])
220-
extends scala.runtime.AbstractFunction1[A, Option[B]] {
221+
extends scala.runtime.AbstractFunction1[A, Option[B]] with Serializable {
221222

222223
def apply(x: A): Option[B] = {
223224
val z = pf.applyOrElse(x, checkFallback[B])
224225
if (!fallbackOccurred(z)) Some(z) else None
225226
}
226227
}
227228

228-
private class Unlifted[A, B] (f: A => Option[B]) extends scala.runtime.AbstractPartialFunction[A, B] {
229+
private class Unlifted[A, B] (f: A => Option[B]) extends scala.runtime.AbstractPartialFunction[A, B] with Serializable {
229230
def isDefinedAt(x: A): Boolean = f(x).isDefined
230231

231232
override def applyOrElse[A1 <: A, B1 >: B](x: A1, default: A1 => B1): B1 = {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package scala
2+
3+
import org.junit.Test
4+
import org.junit.Assert._
5+
import org.junit.runner.RunWith
6+
import org.junit.runners.JUnit4
7+
8+
@RunWith(classOf[JUnit4])
9+
class PartialFunctionSerializationTest {
10+
val pf1: PartialFunction[Int, Int] = {
11+
case n if n > 0 => 1
12+
}
13+
14+
val pf2: PartialFunction[Int, Int] = {
15+
case n if n <= 0 => 2
16+
}
17+
18+
19+
private def assertSerializable[A,B](fn: A => B) = {
20+
import java.io._
21+
22+
new ObjectOutputStream(new ByteArrayOutputStream()).writeObject(fn)
23+
}
24+
25+
@Test def canSerializeLiteral= assertSerializable(pf1)
26+
27+
@Test def canSerializeLifted= assertSerializable(pf1.lift)
28+
29+
@Test def canSerializeOrElse = assertSerializable(pf1 orElse pf2)
30+
31+
@Test def canSerializeUnlifted = assertSerializable(Function.unlift((x: Int) => Some(x)))
32+
33+
@Test def canSerializeAndThen = assertSerializable(pf1.andThen((x: Int) => x))
34+
}

0 commit comments

Comments
 (0)