diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/library/scala/reflect/ClassTag.scala | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala index 33c5cee783..bced505273 100644 --- a/src/library/scala/reflect/ClassTag.scala +++ b/src/library/scala/reflect/ClassTag.scala @@ -70,26 +70,36 @@ trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serial * `SomeExtractor(...)` is turned into `ct(SomeExtractor(...))` if `T` in `SomeExtractor.unapply(x: T)` * is uncheckable, but we have an instance of `ClassTag[T]`. */ - def unapply(x: Any): Option[T] = unapply_impl(x) - def unapply(x: Byte): Option[T] = unapply_impl(x) - def unapply(x: Short): Option[T] = unapply_impl(x) - def unapply(x: Char): Option[T] = unapply_impl(x) - def unapply(x: Int): Option[T] = unapply_impl(x) - def unapply(x: Long): Option[T] = unapply_impl(x) - def unapply(x: Float): Option[T] = unapply_impl(x) - def unapply(x: Double): Option[T] = unapply_impl(x) - def unapply(x: Boolean): Option[T] = unapply_impl(x) - def unapply(x: Unit): Option[T] = unapply_impl(x) + def unapply(x: Any): Option[T] = x match { + case null => None + case b: Byte => unapply(b) + case s: Short => unapply(s) + case c: Char => unapply(c) + case i: Int => unapply(i) + case l: Long => unapply(l) + case f: Float => unapply(f) + case d: Double => unapply(d) + case b: Boolean => unapply(b) + case u: Unit => unapply(u) + case a: Any => unapplyImpl(a) + } - private def unapply_impl[U: ClassTag](x: U): Option[T] = - if (x == null) None - else { - val staticClass = classTag[U].runtimeClass - val dynamicClass = x.getClass - val effectiveClass = if (staticClass.isPrimitive) staticClass else dynamicClass - val conforms = runtimeClass.isAssignableFrom(effectiveClass) - if (conforms) Some(x.asInstanceOf[T]) else None - } + // TODO: Inline the bodies of these into the Any-accepting unapply overload above and delete them. + // This cannot be done until at least 2.12.0 for reasons of binary compatibility + def unapply(x: Byte) : Option[T] = unapplyImpl(x, classOf[Byte]) + def unapply(x: Short) : Option[T] = unapplyImpl(x, classOf[Short]) + def unapply(x: Char) : Option[T] = unapplyImpl(x, classOf[Char]) + def unapply(x: Int) : Option[T] = unapplyImpl(x, classOf[Int]) + def unapply(x: Long) : Option[T] = unapplyImpl(x, classOf[Long]) + def unapply(x: Float) : Option[T] = unapplyImpl(x, classOf[Float]) + def unapply(x: Double) : Option[T] = unapplyImpl(x, classOf[Double]) + def unapply(x: Boolean) : Option[T] = unapplyImpl(x, classOf[Boolean]) + def unapply(x: Unit) : Option[T] = unapplyImpl(x, classOf[Unit]) + + private[this] def unapplyImpl(x: Any, alternative: jClass[_] = null): Option[T] = { + val conforms = runtimeClass.isAssignableFrom(x.getClass) || (alternative != null && runtimeClass.isAssignableFrom(alternative)) + if (conforms) Some(x.asInstanceOf[T]) else None + } // case class accessories override def canEqual(x: Any) = x.isInstanceOf[ClassTag[_]] |