Skip to content

Commit 3131803

Browse files
committed
Fix inductive implicits performance regression
The fix for #6058 in #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 afb7a8b commit 3131803

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
@@ -1406,9 +1406,10 @@ abstract class SearchHistory { outer =>
14061406
if (cand1.ref == cand.ref) {
14071407
val wideTp = tp.widenExpr
14081408
lazy val wildTp = wildApprox(wideTp)
1409+
lazy val tpSize = wideTp.typeSize
14091410
if (belowByname && (wildTp <:< wildPt)) false
1410-
else if ((wideTp.typeSize < ptSize && wideTp.coveringSet == ptCoveringSet) || (wildTp =:= wildPt)) true
1411-
else loop(tl, isByname(tp) || belowByname)
1411+
else if (tpSize > ptSize || wideTp.coveringSet != ptCoveringSet) loop(tl, isByname(tp) || belowByname)
1412+
else tpSize < ptSize || wildTp =:= wildPt || loop(tl, isByname(tp) || belowByname)
14121413
}
14131414
else loop(tl, isByname(tp) || belowByname)
14141415
}

0 commit comments

Comments
 (0)