diff options
author | Paul Phillips <paulp@improving.org> | 2012-11-01 12:58:43 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-11-02 00:07:25 -0700 |
commit | 64258cf019fb7ebfd9a78451236dac9c676f120b (patch) | |
tree | e573ddc51f7b5c6b262f13ad4b3c1713491d13f3 /src/reflect | |
parent | dd803205a0796068661b7a180c583fa1424cd3ef (diff) | |
download | scala-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')
-rw-r--r-- | src/reflect/scala/reflect/internal/Symbols.scala | 19 |
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 |