diff options
4 files changed, 28 insertions, 9 deletions
diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index 59d42b933f..cd31183d73 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -241,6 +241,7 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy val applyDynamic: NameType = "applyDynamic" val isArray: NameType = "isArray" val isDefinedAt: NameType = "isDefinedAt" + val isDefinedAtCurrent: NameType = "isDefinedAtCurrent" val isEmpty: NameType = "isEmpty" val isInstanceOf_ : NameType = "isInstanceOf" val java: NameType = "java" @@ -248,6 +249,7 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy val length: NameType = "length" val lengthCompare: NameType = "lengthCompare" val lift_ : NameType = "lift" + val macro_ : NameType = "macro" val main: NameType = "main" val map: NameType = "map" val missingCase: NameType = "missingCase" diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index c4bdb73744..f8cca67da7 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -216,7 +216,7 @@ abstract class UnCurry extends InfoTransform /* Transform a function node (x_1,...,x_n) => body of type FunctionN[T_1, .., T_N, R] to * - * class $anon() extends Object() with FunctionN[T_1, .., T_N, R] with ScalaObject { + * class $anon() extends AbstractFunctionN[T_1, .., T_N, R] with Serializable { * def apply(x_1: T_1, ..., x_N: T_n): R = body * } * new $anon() @@ -225,10 +225,14 @@ abstract class UnCurry extends InfoTransform * body = expr match { case P_i if G_i => E_i }_i=1..n * to: * - * class $anon() extends Object() with PartialFunction[T, R] with ScalaObject { + * class $anon() extends AbstractPartialFunction[T, R] with Serializable { * def apply(x: T): R = (expr: @unchecked) match { - * { case P_i if G_i => E_i }_i=1..n - * def isDefinedAt(x: T): boolean = (x: @unchecked) match { + * case P_1 if G_1 => E_1 + * ... + * case P_n if G_n => true + * case _ => this.missingCase(x) + * } + * def isDefinedAtCurrent(x: T): boolean = (x: @unchecked) match { * case P_1 if G_1 => true * ... * case P_n if G_n => true @@ -237,9 +241,10 @@ abstract class UnCurry extends InfoTransform * } * new $anon() * - * However, if one of the patterns P_i if G_i is a default pattern, generate instead + * However, if one of the patterns P_i if G_i is a default pattern, + * drop the last default clause in tghe definition of `apply` and generate for `isDefinedAtCurrent` instead * - * def isDefinedAt(x: T): boolean = true + * def isDefinedAtCurrent(x: T): boolean = true */ def transformFunction(fun: Function): Tree = { val fun1 = deEta(fun) @@ -274,7 +279,11 @@ abstract class UnCurry extends InfoTransform DefDef(Modifiers(FINAL), nme.apply, Nil, List(fun.vparams), TypeTree(restpe), body) setSymbol applyMethod } def isDefinedAtMethodDef() = { - val m = anonClass.newMethod(fun.pos, nme.isDefinedAt) setFlag FINAL + val isDefinedAtName = { + if (anonClass.info.member(nme.isDefinedAtCurrent) != NoSymbol) nme.isDefinedAtCurrent + else nme.isDefinedAt + } + val m = anonClass.newMethod(fun.pos, isDefinedAtName) setFlag FINAL m setInfo MethodType(m newSyntheticValueParams formals, BooleanClass.tpe) anonClass.info.decls enter m val vparam = fun.vparams.head.symbol diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala index ac721b88bc..254a610648 100644 --- a/src/library/scala/PartialFunction.scala +++ b/src/library/scala/PartialFunction.scala @@ -48,6 +48,9 @@ trait PartialFunction[-A, +B] extends (A => B) { else that.apply(x) } + def orElseFast[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]) : PartialFunction[A1, B1] = + orElse(that) + /** Composes this partial function with a transformation function that * gets applied to results of this partial function. * @param k the transformation function @@ -90,6 +93,7 @@ object PartialFunction { def isDefinedAt(x: Any) = false def apply(x: Any): Nothing = throw new MatchError(x) override def orElse[A1, B1](that: PartialFunction[A1, B1]): PartialFunction[A1, B1] = that + override def orElseFast[A1, B1](that: PartialFunction[A1, B1]): PartialFunction[A1, B1] = that override def lift = (x: Any) => None } def empty[A, B] : PartialFunction[A, B] = empty_pf diff --git a/src/library/scala/runtime/AbstractPartialFunction.scala b/src/library/scala/runtime/AbstractPartialFunction.scala index 2a45ec3671..b188cbb37d 100644 --- a/src/library/scala/runtime/AbstractPartialFunction.scala +++ b/src/library/scala/runtime/AbstractPartialFunction.scala @@ -32,11 +32,15 @@ abstract class AbstractPartialFunction[-T1, +R] // Question: Need to ensure that fallBack is overwritten before any access // Is the `synchronized` here the right thing to achieve this? // Is there a cheaper way? - def orElseFast[A1 <: T1, B1 >: R](that: PartialFunction[A1, B1]) : PartialFunction[A1, B1] = { + override def orElseFast[A1 <: T1, B1 >: R](that: PartialFunction[A1, B1]) : PartialFunction[A1, B1] = { val result = this.clone.asInstanceOf[AbstractPartialFunction[A1, B1]] result.synchronized { - result.fallBack = this.fallBack orElse that + result.fallBack = this.fallBack orElseFast that result } } +/* + def isDefinedAt(x: T1): scala.Boolean = isDefinedAtCurrent(x) || fallBack.isDefinedAt(x) + def isDefinedAtCurrent(x: T1): scala.Boolean = false +*/ } |