Skip to content

Commit 556d10e

Browse files
committed
Turn some filter operations into filterConserve
replace filter by filterConserve if - the call is warm (called for more than 10% of source lines) - the filter predicate has a high chance of succeeding Avoid filter altogether if there's a faster alternative
1 parent f3211d2 commit 556d10e

File tree

9 files changed

+30
-23
lines changed

9 files changed

+30
-23
lines changed

compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
409409
if isRemovable(param.binder) then remove(param.binder)
410410
else updateEntry(this, param, replacement)
411411

412-
def removeParam(ps: List[TypeParamRef]) = ps.filter(param ne _)
412+
def removeParam(ps: List[TypeParamRef]) = ps.filterConserve(param ne _)
413413

414414
def replaceParam(tp: Type, atPoly: TypeLambda, atIdx: Int): Type =
415415
current.ensureNonCyclic(atPoly.paramRefs(atIdx), tp.substParam(param, replacement))

compiler/src/dotty/tools/dotc/core/Types.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -829,8 +829,8 @@ object Types {
829829
*/
830830
final def possibleSamMethods(using Context): Seq[SingleDenotation] = {
831831
record("possibleSamMethods")
832-
abstractTermMembers
833-
.filterNot(m => m.symbol.matchingMember(defn.ObjectType).exists || m.symbol.isSuperAccessor)
832+
abstractTermMembers.filterConserve(m =>
833+
!m.symbol.matchingMember(defn.ObjectType).exists && !m.symbol.isSuperAccessor)
834834
}
835835

836836
/** The set of abstract type members of this type. */

compiler/src/dotty/tools/dotc/transform/Erasure.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,7 @@ object Erasure {
977977
if (takesBridges(ctx.owner)) new Bridges(ctx.owner.asClass, erasurePhase).add(stats0)
978978
else stats0
979979
val (stats2, finalCtx) = super.typedStats(stats1, exprOwner)
980-
(stats2.filter(!_.isEmpty), finalCtx)
980+
(stats2.filterConserve(!_.isEmpty), finalCtx)
981981
}
982982

983983
override def adapt(tree: Tree, pt: Type, locked: TypeVars, tryGadtHealing: Boolean)(using Context): Tree =

compiler/src/dotty/tools/dotc/transform/OverridingPairs.scala

+7-6
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ object OverridingPairs {
3333
* pair has already been treated in a parent class.
3434
* This may be refined in subclasses. @see Bridges for a use case.
3535
*/
36-
protected def parents: Array[Symbol] = base.info.parents.toArray map (_.typeSymbol)
36+
protected def parents: Array[Symbol] = base.info.parents.toArray.map(_.typeSymbol)
3737

3838
/** Does `sym1` match `sym2` so that it qualifies as overriding.
3939
* Types always match. Term symbols match if their membertypes
@@ -64,11 +64,12 @@ object OverridingPairs {
6464
decls
6565
}
6666

67-
private val subParents =
68-
val subParents = MutableSymbolMap[BitSet]()
69-
for (bc <- base.info.baseClasses)
70-
subParents(bc) = BitSet(parents.indices.filter(parents(_).derivesFrom(bc)): _*)
71-
subParents
67+
private val subParents = MutableSymbolMap[BitSet]()
68+
for bc <- base.info.baseClasses do
69+
var bits = BitSet.empty
70+
for i <- 0 until parents.length do
71+
if parents(i).derivesFrom(bc) then bits += i
72+
subParents(bc) = bits
7273

7374
private def hasCommonParentAsSubclass(cls1: Symbol, cls2: Symbol): Boolean =
7475
(subParents(cls1) intersect subParents(cls2)).nonEmpty

compiler/src/dotty/tools/dotc/transform/patmat/Space.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ trait SpaceLogic {
126126
val set = spaces.map(simplify(_)).flatMap {
127127
case Or(ss) => ss
128128
case s => Seq(s)
129-
} filter (_ != Empty)
129+
}.filterConserve(_ != Empty)
130130

131131
if (set.isEmpty) Empty
132132
else if (set.size == 1) set.toList(0)

compiler/src/dotty/tools/dotc/typer/Applications.scala

+3-3
Original file line numberDiff line numberDiff line change
@@ -1832,7 +1832,7 @@ trait Applications extends Compatibility {
18321832
}
18331833

18341834
def narrowBySize(alts: List[TermRef]): List[TermRef] =
1835-
alts.filter(sizeFits(_))
1835+
alts.filterConserve(sizeFits(_))
18361836

18371837
def narrowByShapes(alts: List[TermRef]): List[TermRef] =
18381838
val normArgs = args.mapWithIndexConserve(normArg(alts, _, _))
@@ -1843,11 +1843,11 @@ trait Applications extends Compatibility {
18431843
alts
18441844

18451845
def narrowByTrees(alts: List[TermRef], args: List[Tree], resultType: Type): List[TermRef] = {
1846-
val alts2 = alts.filter(alt =>
1846+
val alts2 = alts.filterConserve(alt =>
18471847
isDirectlyApplicableMethodRef(alt, args, resultType)
18481848
)
18491849
if (alts2.isEmpty && !ctx.isAfterTyper)
1850-
alts.filter(alt =>
1850+
alts.filterConserve(alt =>
18511851
isApplicableMethodRef(alt, args, resultType, keepConstraint = false)
18521852
)
18531853
else

compiler/src/dotty/tools/dotc/typer/Implicits.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1205,7 +1205,7 @@ trait Implicits:
12051205
case retained: SearchSuccess =>
12061206
val newPending =
12071207
if (retained eq found) || remaining.isEmpty then remaining
1208-
else remaining.filter(cand =>
1208+
else remaining.filterConserve(cand =>
12091209
compareCandidate(retained, cand.ref, cand.level) <= 0)
12101210
rank(newPending, retained, rfailures)
12111211
case fail: SearchFailure =>

compiler/src/dotty/tools/dotc/typer/Nullables.scala

+13-7
Original file line numberDiff line numberDiff line change
@@ -399,14 +399,20 @@ object Nullables:
399399
tree match
400400
case Block(stats, expr) =>
401401
var shadowed: Set[(Name, List[Span])] = Set.empty
402-
for case (stat: ValDef) <- stats if stat.mods.is(Mutable) do
403-
for prevSpans <- candidates.put(stat.name, Nil) do
404-
shadowed += (stat.name -> prevSpans)
405-
reachable += stat.name
402+
for stat <- stats do
403+
stat match
404+
case stat: ValDef if stat.mods.is(Mutable) =>
405+
for prevSpans <- candidates.put(stat.name, Nil) do
406+
shadowed += (stat.name -> prevSpans)
407+
reachable += stat.name
408+
case _ =>
406409
traverseChildren(tree)
407-
for case (stat: ValDef) <- stats if stat.mods.is(Mutable) do
408-
for spans <- candidates.remove(stat.name) do
409-
tracked += (stat.nameSpan.start -> spans) // candidates that survive until here are tracked
410+
for stat <- stats do
411+
stat match
412+
case stat: ValDef if stat.mods.is(Mutable) =>
413+
for spans <- candidates.remove(stat.name) do
414+
tracked += (stat.nameSpan.start -> spans) // candidates that survive until here are tracked
415+
case _ =>
410416
candidates ++= shadowed
411417
case Assign(Ident(name), rhs) =>
412418
candidates.get(name) match

compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ trait TypeAssigner {
4040
}
4141

4242
def avoidingType(expr: Tree, bindings: List[Tree])(using Context): Type =
43-
TypeOps.avoid(expr.tpe, localSyms(bindings).filter(_.isTerm))
43+
TypeOps.avoid(expr.tpe, localSyms(bindings).filterConserve(_.isTerm))
4444

4545
def avoidPrivateLeaks(sym: Symbol)(using Context): Type =
4646
if sym.owner.isClass && !sym.isOneOf(JavaOrPrivateOrSynthetic)

0 commit comments

Comments
 (0)