summaryrefslogtreecommitdiff
path: root/src/reflect/scala/reflect/internal/Symbols.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-11-01 12:58:43 -0700
committerPaul Phillips <paulp@improving.org>2012-11-02 00:07:25 -0700
commit64258cf019fb7ebfd9a78451236dac9c676f120b (patch)
treee573ddc51f7b5c6b262f13ad4b3c1713491d13f3 /src/reflect/scala/reflect/internal/Symbols.scala
parentdd803205a0796068661b7a180c583fa1424cd3ef (diff)
downloadscala-64258cf019fb7ebfd9a78451236dac9c676f120b.tar.gz
scala-64258cf019fb7ebfd9a78451236dac9c676f120b.tar.bz2
scala-64258cf019fb7ebfd9a78451236dac9c676f120b.zip
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.
Diffstat (limited to 'src/reflect/scala/reflect/internal/Symbols.scala')
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala19
1 files changed, 15 insertions, 4 deletions
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