From 6c87275af7c1c8ee28c511d8df9724526bbca095 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sun, 26 Jun 2011 07:15:54 +0000 Subject: Avoided a ton of unnecessary garbage by creatin... Avoided a ton of unnecessary garbage by creating singletons for <:< and =:= and giving them to all comers. Mother Earth is pleased. Thanks to Michael Bayne for pointing out the suboptimality of giving everyone their own instance. Review by moors. --- src/library/scala/Predef.scala | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 43bf4181ec..acc9e2b3ad 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -334,21 +334,29 @@ object Predef extends LowPriorityImplicits { // Type Constraints -------------------------------------------------------------- - /** An instance of `A <:< B` witnesses that `A` is a subtype of `B`. + /** + * An instance of `A <:< B` witnesses that `A` is a subtype of `B`. + * Requiring an implicit argument of the type `A <:< B` encodes + * the generalized constraint `A <: B`. * - * Requiring an implicit argument of the type `A <:< B` encodes the generalized constraint `A <: B`. + * @note we need a new type constructor `<:<` and evidence `conforms`, + * as reusing `Function1` and `identity` leads to ambiguities in + * case of type errors (any2stringadd is inferred) * - * @note we need a new type constructor `<:<` and evidence `conforms`, as - * reusing `Function2` and `identity` leads to ambiguities in case of type errors (any2stringadd is inferred) - * to constrain any abstract type T that's in scope in a method's argument list (not just the method's own type parameters) - * simply add an implicit argument of type `T <:< U`, where U is the required upper bound (for lower-bounds, use: `L <:< T`, - * where L is the required lower bound). - * in part contributed by Jason Zaugg + * To constrain any abstract type T that's in scope in a method's + * argument list (not just the method's own type parameters) simply + * add an implicit argument of type `T <:< U`, where U is the required + * upper bound; or for lower-bounds, use: `L <:< T`, where L is the + * required lower bound. + * + * In part contributed by Jason Zaugg. */ @implicitNotFound(msg = "Cannot prove that ${From} <:< ${To}.") sealed abstract class <:<[-From, +To] extends (From => To) with Serializable - implicit def conforms[A]: A <:< A = new (A <:< A) { def apply(x: A) = x } - // not in the <:< companion object because it is also intended to subsume identity (which is no longer implicit) + private[this] final val singleton_<:< = new <:<[Any,Any] { def apply(x: Any): Any = x } + // not in the <:< companion object because it is also + // intended to subsume identity (which is no longer implicit) + implicit def conforms[A]: A <:< A = singleton_<:<.asInstanceOf[A <:< A] /** An instance of `A =:= B` witnesses that the types `A` and `B` are equal. * @@ -356,8 +364,9 @@ object Predef extends LowPriorityImplicits { */ @implicitNotFound(msg = "Cannot prove that ${From} =:= ${To}.") sealed abstract class =:=[From, To] extends (From => To) with Serializable + private[this] final val singleton_=:= = new =:=[Any,Any] { def apply(x: Any): Any = x } object =:= { - implicit def tpEquals[A]: A =:= A = new (A =:= A) {def apply(x: A) = x} + implicit def tpEquals[A]: A =:= A = singleton_=:=.asInstanceOf[A =:= A] } // less useful due to #2781 -- cgit v1.2.3