Skip to content

Commit 6c20cdc

Browse files
milessabinanatoliykmetyuk
authored andcommitted
Fix inductive implicits performance regression
The fix for scala#6058 in scala#6163 caused a significant performance regression in the inductive implicits benchmark because the use of =:= rather than == in the divergence check was significantly slower. It is the right test however, so we need a quicker check to rule out negative cases. We're already computing the covering sets and sizes of the two types being compared. tp1 =:= tp2 should entail (sz1 == sz2 && cs1 == cs2), so the contrapositive (sz1 != sz2 || cs1 != cs2) should entail that !(tp1 =:= tp2). However the covering set and size computations were incorrect (they missed types mentioned in bounds which should have been included, and included symbols for unsolved type variables which should not). This commit fixes the latter issue, which allows covering set and size tests to be used to avoid expensive full type equality tests.
1 parent 933f075 commit 6c20cdc

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

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

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4973,6 +4973,14 @@ object Types {
49734973
foldOver(n + 1, tp)
49744974
case tp: TypeRef if tp.info.isTypeAlias =>
49754975
apply(n, tp.superType)
4976+
case tp: TermRef =>
4977+
apply(n, tp.underlying)
4978+
case tp: TypeParamRef =>
4979+
ctx.typerState.constraint.entry(tp) match {
4980+
case tb: TypeBounds => foldOver(n, tb)
4981+
case NoType => foldOver(n, tp.underlying)
4982+
case inst => foldOver(n, inst)
4983+
}
49764984
case _ =>
49774985
foldOver(n, tp)
49784986
}
@@ -4990,10 +4998,18 @@ object Types {
49904998
foldOver(cs + sym, tp)
49914999
case tp: TypeRef if tp.info.isTypeAlias =>
49925000
apply(cs, tp.superType)
4993-
case tp: TypeBounds =>
4994-
foldOver(cs, tp)
4995-
case other =>
5001+
case tp: TypeRef if tp.prefix.isValueType =>
49965002
foldOver(cs + sym, tp)
5003+
case tp: TermRef =>
5004+
apply(cs, tp.underlying)
5005+
case tp: TypeParamRef =>
5006+
ctx.typerState.constraint.entry(tp) match {
5007+
case tb: TypeBounds => foldOver(cs, tb)
5008+
case NoType => foldOver(cs, tp.underlying)
5009+
case inst => foldOver(cs, inst)
5010+
}
5011+
case other =>
5012+
foldOver(cs, tp)
49975013
}
49985014
}
49995015
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,9 +1413,10 @@ abstract class SearchHistory { outer =>
14131413
if (cand1.ref == cand.ref) {
14141414
val wideTp = tp.widenExpr
14151415
lazy val wildTp = wildApprox(wideTp)
1416+
lazy val tpSize = wideTp.typeSize
14161417
if (belowByname && (wildTp <:< wildPt)) false
1417-
else if ((wideTp.typeSize < ptSize && wideTp.coveringSet == ptCoveringSet) || (wildTp =:= wildPt)) true
1418-
else loop(tl, isByname(tp) || belowByname)
1418+
else if (tpSize > ptSize || wideTp.coveringSet != ptCoveringSet) loop(tl, isByname(tp) || belowByname)
1419+
else tpSize < ptSize || wildTp =:= wildPt || loop(tl, isByname(tp) || belowByname)
14191420
}
14201421
else loop(tl, isByname(tp) || belowByname)
14211422
}

0 commit comments

Comments
 (0)