summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-06-26 07:15:54 +0000
committerPaul Phillips <paulp@improving.org>2011-06-26 07:15:54 +0000
commit6c87275af7c1c8ee28c511d8df9724526bbca095 (patch)
tree159b915c405c2932c728ad97c3733f48f9d345a5
parent924b5852faaf9074c3ba74631ad694fcc14f708a (diff)
downloadscala-6c87275af7c1c8ee28c511d8df9724526bbca095.tar.gz
scala-6c87275af7c1c8ee28c511d8df9724526bbca095.tar.bz2
scala-6c87275af7c1c8ee28c511d8df9724526bbca095.zip
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.
-rw-r--r--src/library/scala/Predef.scala31
1 files 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