diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/TreeInfo.scala | 59 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Erasure.scala | 79 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/PostErasure.scala | 60 | ||||
-rw-r--r-- | src/library/scala/Enumeration.scala | 3 | ||||
-rw-r--r-- | src/library/scala/collection/BitSetLike.scala | 6 | ||||
-rw-r--r-- | src/library/scala/collection/SortedMapLike.scala | 29 | ||||
-rw-r--r-- | src/library/scala/collection/SortedSetLike.scala | 10 | ||||
-rw-r--r-- | src/library/scala/collection/generic/Sorted.scala | 12 | ||||
-rw-r--r-- | src/library/scala/collection/immutable/RedBlackTree.scala | 102 | ||||
-rw-r--r-- | src/library/scala/collection/immutable/SortedMap.scala | 6 | ||||
-rw-r--r-- | src/library/scala/collection/immutable/TreeMap.scala | 4 | ||||
-rw-r--r-- | src/library/scala/collection/immutable/TreeSet.scala | 1 | ||||
-rw-r--r-- | src/library/scala/collection/mutable/AVLTree.scala | 11 | ||||
-rw-r--r-- | src/library/scala/collection/mutable/TreeSet.scala | 110 | ||||
-rw-r--r-- | src/reflect/scala/reflect/api/ImplicitTags.scala | 108 | ||||
-rw-r--r-- | src/reflect/scala/reflect/api/Types.scala | 105 |
16 files changed, 406 insertions, 299 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala index f53f99a279..6a0f4407fc 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala @@ -14,6 +14,65 @@ package ast abstract class TreeInfo extends scala.reflect.internal.TreeInfo { val global: Global import global._ + import definitions._ + + // arg1.op(arg2) returns (arg1, op.symbol, arg2) + object BinaryOp { + def unapply(t: Tree): Option[(Tree, Symbol, Tree)] = t match { + case Apply(sel @ Select(arg1, _), arg2 :: Nil) => Some((arg1, sel.symbol, arg2)) + case _ => None + } + } + // recv.op[T1, ...] returns (recv, op.symbol, type argument types) + object TypeApplyOp { + def unapply(t: Tree): Option[(Tree, Symbol, List[Type])] = t match { + case TypeApply(sel @ Select(recv, _), targs) => Some((recv, sel.symbol, targs map (_.tpe))) + case _ => None + } + } + + // x.asInstanceOf[T] returns (x, typeOf[T]) + object AsInstanceOf { + def unapply(t: Tree): Option[(Tree, Type)] = t match { + case Apply(TypeApplyOp(recv, Object_asInstanceOf, tpe :: Nil), Nil) => Some((recv, tpe)) + case _ => None + } + } + + // Extractors for value classes. + object ValueClass { + def isValueClass(tpe: Type) = enteringErasure(tpe.typeSymbol.isDerivedValueClass) + def valueUnbox(tpe: Type) = enteringErasure(tpe.typeSymbol.derivedValueClassUnbox) + + // B.unbox. Returns B. + object Unbox { + def unapply(t: Tree): Option[Tree] = t match { + case Apply(sel @ Select(ref, _), Nil) if valueUnbox(ref.tpe) == sel.symbol => Some(ref) + case _ => None + } + } + // new B(v). Returns B and v. + object Box { + def unapply(t: Tree): Option[(Tree, Type)] = t match { + case Apply(sel @ Select(New(tpt), nme.CONSTRUCTOR), v :: Nil) => Some((v, tpt.tpe.finalResultType)) + case _ => None + } + } + // (new B(v)).unbox. returns v. + object BoxAndUnbox { + def unapply(t: Tree): Option[Tree] = t match { + case Unbox(Box(v, tpe)) if isValueClass(tpe) => Some(v) + case _ => None + } + } + // new B(v1) op new B(v2) where op is == or !=. Returns v1, op, v2. + object BoxAndCompare { + def unapply(t: Tree): Option[(Tree, Symbol, Tree)] = t match { + case BinaryOp(Box(v1, tpe1), op @ (Object_== | Object_!=), Box(v2, tpe2)) if isValueClass(tpe1) && tpe1 =:= tpe2 => Some((v1, op, v2)) + case _ => None + } + } + } /** Is tree legal as a member definition of an interface? */ diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index f380b9d04f..8287c1f631 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -21,6 +21,7 @@ abstract class Erasure extends AddInterfaces import global._ import definitions._ import CODE._ + import treeInfo._ val phaseName: String = "erasure" @@ -357,41 +358,10 @@ abstract class Erasure extends AddInterfaces override def newTyper(context: Context) = new Eraser(context) - private def safeToRemoveUnbox(cls: Symbol): Boolean = - (cls == definitions.NullClass) || isBoxedValueClass(cls) - - /** An extractor object for unboxed expressions (maybe subsumed by posterasure?) */ - object Unboxed { - def unapply(tree: Tree): Option[Tree] = tree match { - case Apply(fn, List(arg)) if isUnbox(fn.symbol) && safeToRemoveUnbox(arg.tpe.typeSymbol) => - Some(arg) - case Apply( - TypeApply( - cast @ Select( - Apply( - sel @ Select(arg, acc), - List()), - asinstanceof), - List(tpt)), - List()) - if cast.symbol == Object_asInstanceOf && - tpt.tpe.typeSymbol.isDerivedValueClass && - sel.symbol == tpt.tpe.typeSymbol.derivedValueClassUnbox => - Some(arg) - case _ => - None - } - } - - /** An extractor object for boxed expressions (maybe subsumed by posterasure?) */ - object Boxed { - def unapply(tree: Tree): Option[Tree] = tree match { - case Apply(Select(New(tpt), nme.CONSTRUCTOR), List(arg)) if (tpt.tpe.typeSymbol.isDerivedValueClass) => - Some(arg) - case LabelDef(name, params, Boxed(rhs)) => - Some(treeCopy.LabelDef(tree, name, params, rhs) setType rhs.tpe) - case _ => - None + private def isSafelyRemovableUnbox(fn: Tree, arg: Tree): Boolean = { + isUnbox(fn.symbol) && { + val cls = arg.tpe.typeSymbol + (cls == definitions.NullClass) || isBoxedValueClass(cls) } } @@ -578,12 +548,7 @@ abstract class Erasure extends AddInterfaces val tree1 = tree.tpe match { case ErasedValueType(tref) => val clazz = tref.sym - tree match { - case Unboxed(arg) if arg.tpe.typeSymbol == clazz => - log("shortcircuiting unbox -> box "+arg); arg - case _ => - New(clazz, cast(tree, underlyingOfValueClass(clazz))) - } + New(clazz, cast(tree, underlyingOfValueClass(clazz))) case _ => tree.tpe.typeSymbol match { case UnitClass => @@ -599,7 +564,7 @@ abstract class Erasure extends AddInterfaces * This is important for specialization: calls to the super constructor should not box/unbox specialized * fields (see TupleX). (ID) */ - case Apply(boxFun, List(arg)) if isUnbox(tree.symbol) && safeToRemoveUnbox(arg.tpe.typeSymbol) => + case Apply(boxFun, List(arg)) if isSafelyRemovableUnbox(tree, arg) => log(s"boxing an unbox: ${tree.symbol} -> ${arg.tpe}") arg case _ => @@ -634,24 +599,18 @@ abstract class Erasure extends AddInterfaces case _ => val tree1 = pt match { case ErasedValueType(tref) => - tree match { - case Boxed(arg) if arg.tpe.isInstanceOf[ErasedValueType] => - log("shortcircuiting box -> unbox "+arg) - arg - case _ => - val clazz = tref.sym - log("not boxed: "+tree) - lazy val underlying = underlyingOfValueClass(clazz) - val tree0 = - if (tree.tpe.typeSymbol == NullClass && - isPrimitiveValueClass(underlying.typeSymbol)) { - // convert `null` directly to underlying type, as going - // via the unboxed type would yield a NPE (see SI-5866) - unbox1(tree, underlying) - } else - Apply(Select(adaptToType(tree, clazz.tpe), clazz.derivedValueClassUnbox), List()) - cast(tree0, pt) - } + val clazz = tref.sym + log("not boxed: "+tree) + lazy val underlying = underlyingOfValueClass(clazz) + val tree0 = + if (tree.tpe.typeSymbol == NullClass && + isPrimitiveValueClass(underlying.typeSymbol)) { + // convert `null` directly to underlying type, as going + // via the unboxed type would yield a NPE (see SI-5866) + unbox1(tree, underlying) + } else + Apply(Select(adaptToType(tree, clazz.tpe), clazz.derivedValueClassUnbox), List()) + cast(tree0, pt) case _ => pt.typeSymbol match { case UnitClass => diff --git a/src/compiler/scala/tools/nsc/transform/PostErasure.scala b/src/compiler/scala/tools/nsc/transform/PostErasure.scala index a8dc47046b..2a86d711f1 100644 --- a/src/compiler/scala/tools/nsc/transform/PostErasure.scala +++ b/src/compiler/scala/tools/nsc/transform/PostErasure.scala @@ -9,10 +9,10 @@ package transform * performs peephole optimizations. */ trait PostErasure extends InfoTransform with TypingTransformers { - val global: Global + import global._ - import definitions._ + import treeInfo._ val phaseName: String = "posterasure" @@ -21,51 +21,33 @@ trait PostErasure extends InfoTransform with TypingTransformers { object elimErasedValueType extends TypeMap { def apply(tp: Type) = tp match { - case ConstantType(Constant(tp: Type)) => - ConstantType(Constant(apply(tp))) - case ErasedValueType(tref) => - enteringPhase(currentRun.erasurePhase)(erasure.erasedValueClassArg(tref)) - case _ => mapOver(tp) + case ConstantType(Constant(tp: Type)) => ConstantType(Constant(apply(tp))) + case ErasedValueType(tref) => enteringErasure(erasure.erasedValueClassArg(tref)) + case _ => mapOver(tp) } } def transformInfo(sym: Symbol, tp: Type) = elimErasedValueType(tp) class PostErasureTransformer(unit: CompilationUnit) extends TypingTransformer(unit) { + override def transform(tree: Tree) = { + def finish(res: Tree) = logResult(s"Posterasure reduction\n Old: $tree\n New")(res) + + /** We use the name of the operation being performed and not the symbol + * itself because the symbol hails from the boxed class, and this transformation + * exists to operate directly on the values. So we are for instance looking + * up == on an lhs of type Int, whereas the symbol which has been passed in + * is from java.lang.Integer. + */ + def binop(lhs: Tree, op: Symbol, rhs: Tree) = + finish(localTyper typed (Apply(Select(lhs, op.name) setPos tree.pos, rhs :: Nil) setPos tree.pos)) - override def transform(tree: Tree) = super.transform(tree) setType elimErasedValueType(tree.tpe) match { - case // new C(arg).underlying ==> arg - Apply(sel @ Select( - Apply(Select(New(tpt), nme.CONSTRUCTOR), List(arg)), - acc), List()) - if enteringPhase(currentRun.erasurePhase) { - tpt.tpe.typeSymbol.isDerivedValueClass && - sel.symbol == tpt.tpe.typeSymbol.derivedValueClassUnbox - } => - if (settings.debug.value) log("Removing "+tree+" -> "+arg) - arg - case // new C(arg1) == new C(arg2) ==> arg1 == arg2 - Apply(sel @ Select( - Apply(Select(New(tpt1), nme.CONSTRUCTOR), List(arg1)), - cmp), - List(Apply(Select(New(tpt2), nme.CONSTRUCTOR), List(arg2)))) - if enteringPhase(currentRun.erasurePhase) { - tpt1.tpe.typeSymbol.isDerivedValueClass && - (sel.symbol == Object_== || sel.symbol == Object_!=) && - tpt2.tpe.typeSymbol == tpt1.tpe.typeSymbol - } => - val result = Apply(Select(arg1, cmp) setPos sel.pos, List(arg2)) setPos tree.pos - log("shortcircuiting equality "+tree+" -> "+result) - localTyper.typed(result) - - case // arg.asInstanceOf[T] ==> arg if arg.tpe == T - Apply(TypeApply(cast @ Select(arg, asinstanceof), List(tpt)), List()) - if cast.symbol == Object_asInstanceOf && arg.tpe =:= tpt.tpe => // !!! <:< ? - if (settings.debug.value) log("Shortening "+tree+" -> "+arg) - arg - case tree1 => - tree1 + case AsInstanceOf(v, tpe) if v.tpe <:< tpe => finish(v) // x.asInstanceOf[X] ==> x + case ValueClass.BoxAndUnbox(v) => finish(v) // (new B(v)).unbox ==> v + case ValueClass.BoxAndCompare(v1, op, v2) => binop(v1, op, v2) // new B(v1) == new B(v2) ==> v1 == v2 + case tree => tree } + } } } diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala index 21f0c8fd3e..d522539e83 100644 --- a/src/library/scala/Enumeration.scala +++ b/src/library/scala/Enumeration.scala @@ -254,7 +254,8 @@ abstract class Enumeration (initial: Int) extends Serializable { def contains(v: Value) = nnIds contains (v.id - bottomId) def + (value: Value) = new ValueSet(nnIds + (value.id - bottomId)) def - (value: Value) = new ValueSet(nnIds - (value.id - bottomId)) - def iterator = nnIds.iterator map (id => thisenum.apply(id + bottomId)) + def iterator = nnIds.iterator map (id => thisenum.apply(bottomId + id)) + override def keysIteratorFrom(start: Value) = nnIds keysIteratorFrom start.id map (id => thisenum.apply(bottomId + id)) override def stringPrefix = thisenum + ".ValueSet" /** Creates a bit mask for the zero-adjusted ids in this set as a * new array of longs */ diff --git a/src/library/scala/collection/BitSetLike.scala b/src/library/scala/collection/BitSetLike.scala index d0f4e323c7..bf05331cb1 100644 --- a/src/library/scala/collection/BitSetLike.scala +++ b/src/library/scala/collection/BitSetLike.scala @@ -98,8 +98,10 @@ trait BitSetLike[+This <: BitSetLike[This] with SortedSet[Int]] extends SortedSe fromBitMaskNoCopy(a) } - def iterator: Iterator[Int] = new AbstractIterator[Int] { - private var current = 0 + def iterator: Iterator[Int] = iteratorFrom(0) + + override def keysIteratorFrom(start: Int) = new AbstractIterator[Int] { + private var current = start private val end = nwords * WordLength def hasNext: Boolean = { while (current < end && !self.contains(current)) current += 1 diff --git a/src/library/scala/collection/SortedMapLike.scala b/src/library/scala/collection/SortedMapLike.scala index 57ad3497c7..3c3e6095df 100644 --- a/src/library/scala/collection/SortedMapLike.scala +++ b/src/library/scala/collection/SortedMapLike.scala @@ -42,6 +42,7 @@ self => val map = self.rangeImpl(from, until) new map.DefaultKeySortedSet } + override def keysIteratorFrom(start: A) = self.keysIteratorFrom(start) } /** Add a key/value pair to this map. @@ -76,11 +77,17 @@ self => override def filterKeys(p: A => Boolean): SortedMap[A, B] = new FilteredKeys(p) with SortedMap.Default[A, B] { implicit def ordering: Ordering[A] = self.ordering override def rangeImpl(from : Option[A], until : Option[A]): SortedMap[A, B] = self.rangeImpl(from, until).filterKeys(p) + override def iteratorFrom(start: A) = self iteratorFrom start filter {case (k, _) => p(k)} + override def keysIteratorFrom(start: A) = self keysIteratorFrom start filter p + override def valuesIteratorFrom(start: A) = self iteratorFrom start collect {case (k,v) if p(k) => v} } override def mapValues[C](f: B => C): SortedMap[A, C] = new MappedValues(f) with SortedMap.Default[A, C] { implicit def ordering: Ordering[A] = self.ordering override def rangeImpl(from : Option[A], until : Option[A]): SortedMap[A, C] = self.rangeImpl(from, until).mapValues(f) + override def iteratorFrom(start: A) = (self iteratorFrom start) map {case (k,v) => (k, f(v))} + override def keysIteratorFrom(start: A) = self keysIteratorFrom start + override def valuesIteratorFrom(start: A) = self valuesIteratorFrom start map f } /** Adds a number of elements provided by a traversable object @@ -91,6 +98,28 @@ self => override def ++[B1 >: B](xs: GenTraversableOnce[(A, B1)]): SortedMap[A, B1] = ((repr: SortedMap[A, B1]) /: xs.seq) (_ + _) + /** + * Creates an iterator over all the key/value pairs + * contained in this map having a key greater than or + * equal to `start` according to the ordering of + * this map. x.iteratorFrom(y) is equivalent + * to but often more efficient than x.from(y).iterator. + * + * @param start The lower bound (inclusive) + * on the keys to be returned + */ + def iteratorFrom(start: A): Iterator[(A, B)] + /** + * Creates an iterator over all the values contained in this + * map that are associated with a key greater than or equal to `start` + * according to the ordering of this map. x.valuesIteratorFrom(y) is + * equivalent to but often more efficient than + * x.from(y).valuesIterator. + * + * @param start The lower bound (inclusive) + * on the keys to be returned + */ + def valuesIteratorFrom(start: A): Iterator[B] } diff --git a/src/library/scala/collection/SortedSetLike.scala b/src/library/scala/collection/SortedSetLike.scala index 71b45c72ff..6d1d1ac111 100644 --- a/src/library/scala/collection/SortedSetLike.scala +++ b/src/library/scala/collection/SortedSetLike.scala @@ -40,4 +40,14 @@ self => case that: SortedSet[_] if that.ordering == ordering => that.hasAll(this.iterator) case that => super.subsetOf(that) } + + /** + * Creates an iterator that contains all values from this collection + * greater than or equal to `start` according to the ordering of + * this collection. x.iteratorFrom(y) is equivalent to but will usually + * be more efficient than x.from(y).iterator + * + * @param start The lower-bound (inclusive) of the iterator + */ + def iteratorFrom(start: A): Iterator[A] = keysIteratorFrom(start) } diff --git a/src/library/scala/collection/generic/Sorted.scala b/src/library/scala/collection/generic/Sorted.scala index f962b26bd3..b3847fffc9 100644 --- a/src/library/scala/collection/generic/Sorted.scala +++ b/src/library/scala/collection/generic/Sorted.scala @@ -78,6 +78,18 @@ trait Sorted[K, +This <: Sorted[K, This]] { else until(next) } + + /** + * Creates an iterator over all the keys(or elements) contained in this + * collection greater than or equal to `start` + * according to the ordering of this collection. x.keysIteratorFrom(y) + * is equivalent to but often more efficient than + * x.from(y).keysIterator. + * + * @param start The lower bound (inclusive) + * on the keys to be returned + */ + def keysIteratorFrom(start: K): Iterator[K] protected def hasAll(j: Iterator[K]): Boolean = { val i = keySet.iterator diff --git a/src/library/scala/collection/immutable/RedBlackTree.scala b/src/library/scala/collection/immutable/RedBlackTree.scala index 99f8d95517..1cd0128c05 100644 --- a/src/library/scala/collection/immutable/RedBlackTree.scala +++ b/src/library/scala/collection/immutable/RedBlackTree.scala @@ -24,13 +24,13 @@ import scala.annotation.meta.getter * * @since 2.10 */ -private[immutable] +private[collection] object RedBlackTree { def isEmpty(tree: Tree[_, _]): Boolean = tree eq null - def contains[A](tree: Tree[A, _], x: A)(implicit ordering: Ordering[A]): Boolean = lookup(tree, x) ne null - def get[A, B](tree: Tree[A, B], x: A)(implicit ordering: Ordering[A]): Option[B] = lookup(tree, x) match { + def contains[A: Ordering](tree: Tree[A, _], x: A): Boolean = lookup(tree, x) ne null + def get[A: Ordering, B](tree: Tree[A, B], x: A): Option[B] = lookup(tree, x) match { case null => None case tree => Some(tree.value) } @@ -44,8 +44,27 @@ object RedBlackTree { } def count(tree: Tree[_, _]) = if (tree eq null) 0 else tree.count - def update[A, B, B1 >: B](tree: Tree[A, B], k: A, v: B1, overwrite: Boolean)(implicit ordering: Ordering[A]): Tree[A, B1] = blacken(upd(tree, k, v, overwrite)) - def delete[A, B](tree: Tree[A, B], k: A)(implicit ordering: Ordering[A]): Tree[A, B] = blacken(del(tree, k)) + /** + * Count all the nodes with keys greater than or equal to the lower bound and less than the upper bound. + * The two bounds are optional. + */ + def countInRange[A](tree: Tree[A, _], from: Option[A], to:Option[A])(implicit ordering: Ordering[A]) : Int = + if (tree eq null) 0 else + (from, to) match { + // with no bounds use this node's count + case (None, None) => tree.count + // if node is less than the lower bound, try the tree on the right, it might be in range + case (Some(lb), _) if ordering.lt(tree.key, lb) => countInRange(tree.right, from, to) + // if node is greater than or equal to the upper bound, try the tree on the left, it might be in range + case (_, Some(ub)) if ordering.gteq(tree.key, ub) => countInRange(tree.left, from, to) + // node is in range so the tree on the left will all be less than the upper bound and the tree on the + // right will all be greater than or equal to the lower bound. So 1 for this node plus + // count the subtrees by stripping off the bounds that we don't need any more + case _ => 1 + countInRange(tree.left, from, None) + countInRange(tree.right, None, to) + + } + def update[A: Ordering, B, B1 >: B](tree: Tree[A, B], k: A, v: B1, overwrite: Boolean): Tree[A, B1] = blacken(upd(tree, k, v, overwrite)) + def delete[A: Ordering, B](tree: Tree[A, B], k: A): Tree[A, B] = blacken(del(tree, k)) def rangeImpl[A: Ordering, B](tree: Tree[A, B], from: Option[A], until: Option[A]): Tree[A, B] = (from, until) match { case (Some(from), Some(until)) => this.range(tree, from, until) case (Some(from), None) => this.from(tree, from) @@ -91,9 +110,9 @@ object RedBlackTree { if (tree.right ne null) _foreachKey(tree.right, f) } - def iterator[A, B](tree: Tree[A, B]): Iterator[(A, B)] = new EntriesIterator(tree) - def keysIterator[A, _](tree: Tree[A, _]): Iterator[A] = new KeysIterator(tree) - def valuesIterator[_, B](tree: Tree[_, B]): Iterator[B] = new ValuesIterator(tree) + def iterator[A: Ordering, B](tree: Tree[A, B], start: Option[A] = None): Iterator[(A, B)] = new EntriesIterator(tree, start) + def keysIterator[A: Ordering](tree: Tree[A, _], start: Option[A] = None): Iterator[A] = new KeysIterator(tree, start) + def valuesIterator[A: Ordering, B](tree: Tree[A, B], start: Option[A] = None): Iterator[B] = new ValuesIterator(tree, start) @tailrec def nth[A, B](tree: Tree[A, B], n: Int): Tree[A, B] = { @@ -425,32 +444,28 @@ object RedBlackTree { def unapply[A, B](t: BlackTree[A, B]) = Some((t.key, t.value, t.left, t.right)) } - private[this] abstract class TreeIterator[A, B, R](tree: Tree[A, B]) extends Iterator[R] { + private[this] abstract class TreeIterator[A, B, R](root: Tree[A, B], start: Option[A])(implicit ordering: Ordering[A]) extends Iterator[R] { protected[this] def nextResult(tree: Tree[A, B]): R - override def hasNext: Boolean = next ne null + override def hasNext: Boolean = lookahead ne null - override def next: R = next match { + override def next: R = lookahead match { case null => throw new NoSuchElementException("next on empty iterator") case tree => - next = findNext(tree.right) + lookahead = findLeftMostOrPopOnEmpty(goRight(tree)) nextResult(tree) } @tailrec - private[this] def findNext(tree: Tree[A, B]): Tree[A, B] = { - if (tree eq null) popPath() + private[this] def findLeftMostOrPopOnEmpty(tree: Tree[A, B]): Tree[A, B] = + if (tree eq null) popNext() else if (tree.left eq null) tree - else { - pushPath(tree) - findNext(tree.left) - } - } + else findLeftMostOrPopOnEmpty(goLeft(tree)) - private[this] def pushPath(tree: Tree[A, B]) { + private[this] def pushNext(tree: Tree[A, B]) { try { - path(index) = tree + stackOfNexts(index) = tree index += 1 } catch { case _: ArrayIndexOutOfBoundsException => @@ -462,17 +477,17 @@ object RedBlackTree { * An exception handler is used instead of an if-condition to optimize the normal path. * This makes a large difference in iteration speed! */ - assert(index >= path.length) - path :+= null - pushPath(tree) + assert(index >= stackOfNexts.length) + stackOfNexts :+= null + pushNext(tree) } } - private[this] def popPath(): Tree[A, B] = if (index == 0) null else { + private[this] def popNext(): Tree[A, B] = if (index == 0) null else { index -= 1 - path(index) + stackOfNexts(index) } - private[this] var path = if (tree eq null) null else { + private[this] var stackOfNexts = if (root eq null) null else { /* * According to "Ralf Hinze. Constructing red-black trees" [http://www.cs.ox.ac.uk/ralf.hinze/publications/#P5] * the maximum height of a red-black tree is 2*log_2(n + 2) - 2. @@ -481,22 +496,45 @@ object RedBlackTree { * * We also don't store the deepest nodes in the path so the maximum path length is further reduced by one. */ - val maximumHeight = 2 * (32 - Integer.numberOfLeadingZeros(tree.count + 2 - 1)) - 2 - 1 + val maximumHeight = 2 * (32 - Integer.numberOfLeadingZeros(root.count + 2 - 1)) - 2 - 1 new Array[Tree[A, B]](maximumHeight) } private[this] var index = 0 - private[this] var next: Tree[A, B] = findNext(tree) + private[this] var lookahead: Tree[A, B] = start map startFrom getOrElse findLeftMostOrPopOnEmpty(root) + + /** + * Find the leftmost subtree whose key is equal to the given key, or if no such thing, + * the leftmost subtree with the key that would be "next" after it according + * to the ordering. Along the way build up the iterator's path stack so that "next" + * functionality works. + */ + private[this] def startFrom(key: A) : Tree[A,B] = if (root eq null) null else { + @tailrec def find(tree: Tree[A, B]): Tree[A, B] = + if (tree eq null) popNext + else find( + if (ordering.lteq(key, tree.key)) goLeft(tree) + else goRight(tree) + ) + find(root) + } + + private[this] def goLeft(tree: Tree[A, B]) = { + pushNext(tree) + tree.left + } + + private[this] def goRight(tree: Tree[A, B]) = tree.right } - private[this] class EntriesIterator[A, B](tree: Tree[A, B]) extends TreeIterator[A, B, (A, B)](tree) { + private[this] class EntriesIterator[A: Ordering, B](tree: Tree[A, B], focus: Option[A]) extends TreeIterator[A, B, (A, B)](tree, focus) { override def nextResult(tree: Tree[A, B]) = (tree.key, tree.value) } - private[this] class KeysIterator[A, B](tree: Tree[A, B]) extends TreeIterator[A, B, A](tree) { + private[this] class KeysIterator[A: Ordering, B](tree: Tree[A, B], focus: Option[A]) extends TreeIterator[A, B, A](tree, focus) { override def nextResult(tree: Tree[A, B]) = tree.key } - private[this] class ValuesIterator[A, B](tree: Tree[A, B]) extends TreeIterator[A, B, B](tree) { + private[this] class ValuesIterator[A: Ordering, B](tree: Tree[A, B], focus: Option[A]) extends TreeIterator[A, B, B](tree, focus) { override def nextResult(tree: Tree[A, B]) = tree.value } } diff --git a/src/library/scala/collection/immutable/SortedMap.scala b/src/library/scala/collection/immutable/SortedMap.scala index eb04231c55..5e833f87af 100644 --- a/src/library/scala/collection/immutable/SortedMap.scala +++ b/src/library/scala/collection/immutable/SortedMap.scala @@ -82,11 +82,17 @@ self => override def filterKeys(p: A => Boolean): SortedMap[A, B] = new FilteredKeys(p) with SortedMap.Default[A, B] { implicit def ordering: Ordering[A] = self.ordering override def rangeImpl(from : Option[A], until : Option[A]): SortedMap[A, B] = self.rangeImpl(from, until).filterKeys(p) + override def iteratorFrom(start: A) = self iteratorFrom start filter {case (k, _) => p(k)} + override def keysIteratorFrom(start : A) = self keysIteratorFrom start filter p + override def valuesIteratorFrom(start : A) = self iteratorFrom start collect {case (k,v) if p(k) => v} } override def mapValues[C](f: B => C): SortedMap[A, C] = new MappedValues(f) with SortedMap.Default[A, C] { implicit def ordering: Ordering[A] = self.ordering override def rangeImpl(from : Option[A], until : Option[A]): SortedMap[A, C] = self.rangeImpl(from, until).mapValues(f) + override def iteratorFrom(start: A) = self iteratorFrom start map {case (k, v) => (k, f(v))} + override def keysIteratorFrom(start : A) = self keysIteratorFrom start + override def valuesIteratorFrom(start : A) = self valuesIteratorFrom start map f } } diff --git a/src/library/scala/collection/immutable/TreeMap.scala b/src/library/scala/collection/immutable/TreeMap.scala index 9a87d8636b..a6a6b75c32 100644 --- a/src/library/scala/collection/immutable/TreeMap.scala +++ b/src/library/scala/collection/immutable/TreeMap.scala @@ -189,9 +189,13 @@ class TreeMap[A, +B] private (tree: RB.Tree[A, B])(implicit val ordering: Orderi * @return the new iterator */ override def iterator: Iterator[(A, B)] = RB.iterator(tree) + override def iteratorFrom(start: A): Iterator[(A, B)] = RB.iterator(tree, Some(start)) override def keysIterator: Iterator[A] = RB.keysIterator(tree) + override def keysIteratorFrom(start: A): Iterator[A] = RB.keysIterator(tree, Some(start)) + override def valuesIterator: Iterator[B] = RB.valuesIterator(tree) + override def valuesIteratorFrom(start: A): Iterator[B] = RB.valuesIterator(tree, Some(start)) override def contains(key: A): Boolean = RB.contains(tree, key) override def isDefinedAt(key: A): Boolean = RB.contains(tree, key) diff --git a/src/library/scala/collection/immutable/TreeSet.scala b/src/library/scala/collection/immutable/TreeSet.scala index 8bceb936aa..67668b3bef 100644 --- a/src/library/scala/collection/immutable/TreeSet.scala +++ b/src/library/scala/collection/immutable/TreeSet.scala @@ -144,6 +144,7 @@ class TreeSet[A] private (tree: RB.Tree[A, Unit])(implicit val ordering: Orderin * @return the new iterator */ def iterator: Iterator[A] = RB.keysIterator(tree) + override def keysIteratorFrom(start: A): Iterator[A] = RB.keysIterator(tree, Some(start)) override def foreach[U](f: A => U) = RB.foreachKey(tree, f) diff --git a/src/library/scala/collection/mutable/AVLTree.scala b/src/library/scala/collection/mutable/AVLTree.scala index 157e5dae62..da63778fcc 100644 --- a/src/library/scala/collection/mutable/AVLTree.scala +++ b/src/library/scala/collection/mutable/AVLTree.scala @@ -15,7 +15,7 @@ package mutable * An immutable AVL Tree implementation used by mutable.TreeSet * * @author Lucien Pereira - * + * @deprecated("AVLTree and its related classes are being removed from the standard library since they're not different enough from RedBlackTree to justify keeping them.", "2.11") */ private[mutable] sealed trait AVLTree[+A] extends Serializable { def balance: Int @@ -65,12 +65,18 @@ private[mutable] sealed trait AVLTree[+A] extends Serializable { def doubleRightRotation[B >: A]: Node[B] = sys.error("Should not happen.") } +/** + * @deprecated("AVLTree and its related classes are being removed from the standard library since they're not different enough from RedBlackTree to justify keeping them.", "2.11") + */ private case object Leaf extends AVLTree[Nothing] { override val balance: Int = 0 override val depth: Int = -1 } +/** + * @deprecated("AVLTree and its related classes are being removed from the standard library since they're not different enough from RedBlackTree to justify keeping them.", "2.11") + */ private case class Node[A](val data: A, val left: AVLTree[A], val right: AVLTree[A]) extends AVLTree[A] { override val balance: Int = right.depth - left.depth @@ -205,6 +211,9 @@ private case class Node[A](val data: A, val left: AVLTree[A], val right: AVLTree } } +/** + * @deprecated("AVLTree and its related classes are being removed from the standard library since they're not different enough from RedBlackTree to justify keeping them.", "2.11") + */ private class AVLIterator[A](root: Node[A]) extends Iterator[A] { val stack = mutable.ArrayStack[Node[A]](root) diveLeft() diff --git a/src/library/scala/collection/mutable/TreeSet.scala b/src/library/scala/collection/mutable/TreeSet.scala index 5197af1b04..9113d8221b 100644 --- a/src/library/scala/collection/mutable/TreeSet.scala +++ b/src/library/scala/collection/mutable/TreeSet.scala @@ -10,6 +10,8 @@ package scala.collection package mutable import generic._ +import scala.collection.immutable.{RedBlackTree => RB} +import scala.runtime.ObjectRef /** * @define Coll `mutable.TreeSet` @@ -29,95 +31,81 @@ object TreeSet extends MutableSortedSetFactory[TreeSet] { } /** - * A mutable SortedSet using an immutable AVL Tree as underlying data structure. + * A mutable SortedSet using an immutable RedBlack Tree as underlying data structure. * * @author Lucien Pereira * */ -class TreeSet[A](implicit val ordering: Ordering[A]) extends SortedSet[A] with SetLike[A, TreeSet[A]] +class TreeSet[A] private (treeRef: ObjectRef[RB.Tree[A, Null]], from: Option[A], until: Option[A])(implicit val ordering: Ordering[A]) + extends SortedSet[A] with SetLike[A, TreeSet[A]] with SortedSetLike[A, TreeSet[A]] with Set[A] with Serializable { - // Projection constructor - private def this(base: Option[TreeSet[A]], from: Option[A], until: Option[A])(implicit ordering: Ordering[A]) { - this(); - this.base = base - this.from = from - this.until = until - } - - private var base: Option[TreeSet[A]] = None - - private var from: Option[A] = None - - private var until: Option[A] = None - - private var avl: AVLTree[A] = Leaf - - private var cardinality: Int = 0 + def this()(implicit ordering: Ordering[A]) = this(new ObjectRef(null), None, None) - def resolve: TreeSet[A] = base.getOrElse(this) - - private def isLeftAcceptable(from: Option[A], ordering: Ordering[A])(a: A): Boolean = - from.map(x => ordering.gteq(a, x)).getOrElse(true) - - private def isRightAcceptable(until: Option[A], ordering: Ordering[A])(a: A): Boolean = - until.map(x => ordering.lt(a, x)).getOrElse(true) - - /** - * Cardinality store the set size, unfortunately a - * set view (given by rangeImpl) - * cannot take advantage of this optimisation - * - */ - override def size: Int = base.map(_ => super.size).getOrElse(cardinality) + override def size: Int = RB.countInRange(treeRef.elem, from, until) override def stringPrefix = "TreeSet" override def empty: TreeSet[A] = TreeSet.empty - override def rangeImpl(from: Option[A], until: Option[A]): TreeSet[A] = new TreeSet(Some(this), from, until) + private def pickBound(comparison: (A, A) => A, oldBound: Option[A], newBound: Option[A]) = (newBound, oldBound) match { + case (Some(newB), Some(oldB)) => Some(comparison(newB, oldB)) + case (None, _) => oldBound + case _ => newBound + } + + override def rangeImpl(fromArg: Option[A], untilArg: Option[A]): TreeSet[A] = { + val newFrom = pickBound(ordering.max, fromArg, from) + val newUntil = pickBound(ordering.min, untilArg, until) + + new TreeSet(treeRef, newFrom, newUntil) + } override def -=(elem: A): this.type = { - try { - resolve.avl = resolve.avl.remove(elem, ordering) - resolve.cardinality = resolve.cardinality - 1 - } catch { - case e: NoSuchElementException => () - } + treeRef.elem = RB.delete(treeRef.elem, elem) this } override def +=(elem: A): this.type = { - try { - resolve.avl = resolve.avl.insert(elem, ordering) - resolve.cardinality = resolve.cardinality + 1 - } catch { - case e: IllegalArgumentException => () - } + treeRef.elem = RB.update(treeRef.elem, elem, null, false) this } /** * Thanks to the immutable nature of the - * underlying AVL Tree, we can share it with + * underlying Tree, we can share it with * the clone. So clone complexity in time is O(1). * */ - override def clone(): TreeSet[A] = { - val clone = new TreeSet[A](base, from, until) - clone.avl = resolve.avl - clone.cardinality = resolve.cardinality - clone - } + override def clone(): TreeSet[A] = + new TreeSet[A](new ObjectRef(treeRef.elem), from, until) + + private val notProjection = !(from.isDefined || until.isDefined) override def contains(elem: A): Boolean = { - isLeftAcceptable(from, ordering)(elem) && - isRightAcceptable(until, ordering)(elem) && - resolve.avl.contains(elem, ordering) - } + def leftAcceptable: Boolean = from match { + case Some(lb) => ordering.gteq(elem, lb) + case _ => true + } - override def iterator: Iterator[A] = resolve.avl.iterator - .dropWhile(e => !isLeftAcceptable(from, ordering)(e)) - .takeWhile(e => isRightAcceptable(until, ordering)(e)) + def rightAcceptable: Boolean = until match { + case Some(ub) => ordering.lt(elem, ub) + case _ => true + } + + (notProjection || (leftAcceptable && rightAcceptable)) && + RB.contains(treeRef.elem, elem) + } + override def iterator: Iterator[A] = iteratorFrom(None) + + override def keysIteratorFrom(start: A) = iteratorFrom(Some(start)) + + private def iteratorFrom(start: Option[A]) = { + val it = RB.keysIterator(treeRef.elem, pickBound(ordering.max, from, start)) + until match { + case None => it + case Some(ub) => it takeWhile (k => ordering.lt(k, ub)) + } + } } diff --git a/src/reflect/scala/reflect/api/ImplicitTags.scala b/src/reflect/scala/reflect/api/ImplicitTags.scala new file mode 100644 index 0000000000..3f377d6cff --- /dev/null +++ b/src/reflect/scala/reflect/api/ImplicitTags.scala @@ -0,0 +1,108 @@ +package scala.reflect +package api + +trait ImplicitTags { + self: Types => + + /** A tag that preserves the identity of the `Type` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val TypeTagg: ClassTag[Type] + + /** A tag that preserves the identity of the `SingletonType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val SingletonTypeTag: ClassTag[SingletonType] + + /** A tag that preserves the identity of the `ThisType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val ThisTypeTag: ClassTag[ThisType] + + /** A tag that preserves the identity of the `SingleType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val SingleTypeTag: ClassTag[SingleType] + + /** A tag that preserves the identity of the `SuperType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val SuperTypeTag: ClassTag[SuperType] + + /** A tag that preserves the identity of the `ConstantType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val ConstantTypeTag: ClassTag[ConstantType] + + /** A tag that preserves the identity of the `TypeRef` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val TypeRefTag: ClassTag[TypeRef] + + /** A tag that preserves the identity of the `CompoundType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val CompoundTypeTag: ClassTag[CompoundType] + + /** A tag that preserves the identity of the `RefinedType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val RefinedTypeTag: ClassTag[RefinedType] + + /** A tag that preserves the identity of the `ClassInfoType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val ClassInfoTypeTag: ClassTag[ClassInfoType] + + /** A tag that preserves the identity of the `MethodType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val MethodTypeTag: ClassTag[MethodType] + + /** A tag that preserves the identity of the `NullaryMethodType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val NullaryMethodTypeTag: ClassTag[NullaryMethodType] + + /** A tag that preserves the identity of the `PolyType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val PolyTypeTag: ClassTag[PolyType] + + /** A tag that preserves the identity of the `ExistentialType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val ExistentialTypeTag: ClassTag[ExistentialType] + + /** A tag that preserves the identity of the `AnnotatedType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val AnnotatedTypeTag: ClassTag[AnnotatedType] + + /** A tag that preserves the identity of the `TypeBounds` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val TypeBoundsTag: ClassTag[TypeBounds] + + /** A tag that preserves the identity of the `BoundedWildcardType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val BoundedWildcardTypeTag: ClassTag[BoundedWildcardType] +} diff --git a/src/reflect/scala/reflect/api/Types.scala b/src/reflect/scala/reflect/api/Types.scala index 143438b8f5..e8e9e9c048 100644 --- a/src/reflect/scala/reflect/api/Types.scala +++ b/src/reflect/scala/reflect/api/Types.scala @@ -50,7 +50,8 @@ package api * * @contentDiagram hideNodes "*Api" */ -trait Types { self: Universe => +trait Types extends ImplicitTags { + self: Universe => /** The type of Scala types, and also Scala type signatures. * (No difference is internally made between the two). @@ -59,12 +60,6 @@ trait Types { self: Universe => */ type Type >: Null <: TypeApi - /** A tag that preserves the identity of the `Type` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val TypeTagg: ClassTag[Type] - /** This constant is used as a special value that indicates that no meaningful type exists. * @group Types */ @@ -256,12 +251,6 @@ trait Types { self: Universe => */ type SingletonType >: Null <: Type - /** A tag that preserves the identity of the `SingletonType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val SingletonTypeTag: ClassTag[SingletonType] - /** A singleton type that describes types of the form on the left with the * corresponding `ThisType` representation to the right: * {{{ @@ -272,12 +261,6 @@ trait Types { self: Universe => */ type ThisType >: Null <: AnyRef with SingletonType with ThisTypeApi - /** A tag that preserves the identity of the `ThisType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val ThisTypeTag: ClassTag[ThisType] - /** The constructor/extractor for `ThisType` instances. * @group Extractors */ @@ -316,12 +299,6 @@ trait Types { self: Universe => */ type SingleType >: Null <: AnyRef with SingletonType with SingleTypeApi - /** A tag that preserves the identity of the `SingleType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val SingleTypeTag: ClassTag[SingleType] - /** The constructor/extractor for `SingleType` instances. * @group Extractors */ @@ -361,12 +338,6 @@ trait Types { self: Universe => */ type SuperType >: Null <: AnyRef with SingletonType with SuperTypeApi - /** A tag that preserves the identity of the `SuperType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val SuperTypeTag: ClassTag[SuperType] - /** The constructor/extractor for `SuperType` instances. * @group Extractors */ @@ -406,12 +377,6 @@ trait Types { self: Universe => */ type ConstantType >: Null <: AnyRef with SingletonType with ConstantTypeApi - /** A tag that preserves the identity of the `ConstantType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val ConstantTypeTag: ClassTag[ConstantType] - /** The constructor/extractor for `ConstantType` instances. * @group Extractors */ @@ -450,12 +415,6 @@ trait Types { self: Universe => */ type TypeRef >: Null <: AnyRef with Type with TypeRefApi - /** A tag that preserves the identity of the `TypeRef` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val TypeRefTag: ClassTag[TypeRef] - /** The constructor/extractor for `TypeRef` instances. * @group Extractors */ @@ -497,12 +456,6 @@ trait Types { self: Universe => */ type CompoundType >: Null <: AnyRef with Type - /** A tag that preserves the identity of the `CompoundType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val CompoundTypeTag: ClassTag[CompoundType] - /** The `RefinedType` type defines types of any of the forms on the left, * with their RefinedType representations to the right. * {{{ @@ -515,12 +468,6 @@ trait Types { self: Universe => */ type RefinedType >: Null <: AnyRef with CompoundType with RefinedTypeApi - /** A tag that preserves the identity of the `RefinedType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val RefinedTypeTag: ClassTag[RefinedType] - /** The constructor/extractor for `RefinedType` instances. * @group Extractors */ @@ -567,12 +514,6 @@ trait Types { self: Universe => */ type ClassInfoType >: Null <: AnyRef with CompoundType with ClassInfoTypeApi - /** A tag that preserves the identity of the `ClassInfoType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val ClassInfoTypeTag: ClassTag[ClassInfoType] - /** The constructor/extractor for `ClassInfoType` instances. * @group Extractors */ @@ -610,12 +551,6 @@ trait Types { self: Universe => */ type MethodType >: Null <: AnyRef with Type with MethodTypeApi - /** A tag that preserves the identity of the `MethodType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val MethodTypeTag: ClassTag[MethodType] - /** The constructor/extractor for `MethodType` instances. * @group Extractors */ @@ -660,12 +595,6 @@ trait Types { self: Universe => */ type NullaryMethodType >: Null <: AnyRef with Type with NullaryMethodTypeApi - /** A tag that preserves the identity of the `NullaryMethodType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val NullaryMethodTypeTag: ClassTag[NullaryMethodType] - /** The constructor/extractor for `NullaryMethodType` instances. * @group Extractors */ @@ -696,12 +625,6 @@ trait Types { self: Universe => */ type PolyType >: Null <: AnyRef with Type with PolyTypeApi - /** A tag that preserves the identity of the `PolyType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val PolyTypeTag: ClassTag[PolyType] - /** The constructor/extractor for `PolyType` instances. * @group Extractors */ @@ -736,12 +659,6 @@ trait Types { self: Universe => */ type ExistentialType >: Null <: AnyRef with Type with ExistentialTypeApi - /** A tag that preserves the identity of the `ExistentialType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val ExistentialTypeTag: ClassTag[ExistentialType] - /** The constructor/extractor for `ExistentialType` instances. * @group Extractors */ @@ -777,12 +694,6 @@ trait Types { self: Universe => */ type AnnotatedType >: Null <: AnyRef with Type with AnnotatedTypeApi - /** A tag that preserves the identity of the `AnnotatedType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val AnnotatedTypeTag: ClassTag[AnnotatedType] - /** The constructor/extractor for `AnnotatedType` instances. * @group Extractors */ @@ -828,12 +739,6 @@ trait Types { self: Universe => */ type TypeBounds >: Null <: AnyRef with Type with TypeBoundsApi - /** A tag that preserves the identity of the `TypeBounds` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val TypeBoundsTag: ClassTag[TypeBounds] - /** The constructor/extractor for `TypeBounds` instances. * @group Extractors */ @@ -885,12 +790,6 @@ trait Types { self: Universe => */ type BoundedWildcardType >: Null <: AnyRef with Type with BoundedWildcardTypeApi - /** A tag that preserves the identity of the `BoundedWildcardType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val BoundedWildcardTypeTag: ClassTag[BoundedWildcardType] - /** The constructor/extractor for `BoundedWildcardType` instances. * @group Extractors */ |