From 64258cf019fb7ebfd9a78451236dac9c676f120b Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 1 Nov 2012 12:58:43 -0700 Subject: Fixed bug in Symbol filtering. If you called filter on an overloaded symbol, it tried to return itself if no alternatives were filtered out. The test being performed, however, would only ever be true if the list call was to the (non-existent) "filterConserve", which is to say that in general, xs ne xs.filter(_ => true) The upshot is that we were creating a new symbol on every filter call to an overloaded symbol. To make completely sure this would be a performance winner, I also eliminated the closure and perform the filtering locally. --- src/reflect/scala/reflect/internal/Symbols.scala | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'src/reflect') diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 8cebfabe6f..53a236fa3c 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -1672,12 +1672,23 @@ trait Symbols extends api.Symbols { self: SymbolTable => def filter(cond: Symbol => Boolean): Symbol = if (isOverloaded) { - val alts = alternatives - val alts1 = alts filter cond - if (alts1 eq alts) this + var changed = false + var alts0: List[Symbol] = alternatives + var alts1: List[Symbol] = Nil + + while (alts0.nonEmpty) { + if (cond(alts0.head)) + alts1 ::= alts0.head + else + changed = true + + alts0 = alts0.tail + } + + if (!changed) this else if (alts1.isEmpty) NoSymbol else if (alts1.tail.isEmpty) alts1.head - else owner.newOverloaded(info.prefix, alts1) + else owner.newOverloaded(info.prefix, alts1.reverse) } else if (cond(this)) this else NoSymbol -- cgit v1.2.3