@@ -17,13 +17,16 @@ import reporting.trace
1717/** Provides methods to compare types.
1818 */
1919class TypeComparer (initctx : Context ) extends DotClass with ConstraintHandling {
20+ import TypeComparer .show
21+
2022 implicit val ctx = initctx
2123
2224 val state = ctx.typerState
2325 import state .constraint
2426
2527 private [this ] var pendingSubTypes : mutable.Set [(Type , Type )] = null
2628 private [this ] var recCount = 0
29+ private [this ] var monitored = false
2730
2831 private [this ] var needsGc = false
2932
@@ -101,9 +104,11 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
101104 if (tp2 eq NoType ) return false
102105 if ((tp2 eq tp1) || (tp2 eq WildcardType )) return true
103106 try isSubType(tp1, tp2)
104- finally
107+ finally {
108+ monitored = false
105109 if (Config .checkConstraintsSatisfiable)
106110 assert(isSatisfiable, constraint.show)
111+ }
107112 }
108113
109114 protected def isSubType (tp1 : Type , tp2 : Type ): Boolean = trace(s " isSubType ${traceInfo(tp1, tp2)}" , subtyping) {
@@ -114,9 +119,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
114119 val savedSuccessCount = successCount
115120 try {
116121 recCount = recCount + 1
117- val result =
118- if (recCount < Config .LogPendingSubTypesThreshold ) firstTry(tp1, tp2)
119- else monitoredIsSubType(tp1, tp2)
122+ if (recCount >= Config .LogPendingSubTypesThreshold ) monitored = true
123+ val result = if (monitored) monitoredIsSubType(tp1, tp2) else firstTry(tp1, tp2)
120124 recCount = recCount - 1
121125 if (! result) state.resetConstraintTo(saved)
122126 else if (recCount == 0 && needsGc) {
@@ -300,6 +304,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
300304 if (isSubType(info1.alias, tp2)) return true
301305 if (tp1.prefix.isStable) return false
302306 case _ =>
307+ if (tp1 eq NothingType ) return tp1 == tp2.bottomType
303308 }
304309 thirdTry(tp1, tp2)
305310 case tp1 : TypeParamRef =>
@@ -1577,7 +1582,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
15771582
15781583 /** Show subtype goal that led to an assertion failure */
15791584 def showGoal (tp1 : Type , tp2 : Type )(implicit ctx : Context ) = {
1580- println(i " assertion failure for $tp1 <:< $tp2, frozen = $frozenConstraint" )
1585+ println(i " assertion failure for ${show( tp1)} <:< ${show( tp2)} , frozen = $frozenConstraint" )
15811586 def explainPoly (tp : Type ) = tp match {
15821587 case tp : TypeParamRef => ctx.echo(s " TypeParamRef ${tp.show} found in ${tp.binder.show}" )
15831588 case tp : TypeRef if tp.symbol.exists => ctx.echo(s " typeref ${tp.show} found in ${tp.symbol.owner.show}" )
@@ -1609,6 +1614,11 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
16091614
16101615object TypeComparer {
16111616
1617+ private [core] def show (res : Any )(implicit ctx : Context ) = res match {
1618+ case res : printing.Showable if ! ctx.settings.YexplainLowlevel .value => res.show
1619+ case _ => String .valueOf(res)
1620+ }
1621+
16121622 /** Show trace of comparison operations when performing `op` as result string */
16131623 def explained [T ](op : Context => T )(implicit ctx : Context ): String = {
16141624 val nestedCtx = ctx.fresh.setTypeComparerFn(new ExplainingTypeComparer (_))
@@ -1619,6 +1629,8 @@ object TypeComparer {
16191629
16201630/** A type comparer that can record traces of subtype operations */
16211631class ExplainingTypeComparer (initctx : Context ) extends TypeComparer (initctx) {
1632+ import TypeComparer .show
1633+
16221634 private [this ] var indent = 0
16231635 private val b = new StringBuilder
16241636
@@ -1635,11 +1647,6 @@ class ExplainingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
16351647 res
16361648 }
16371649
1638- private def show (res : Any ) = res match {
1639- case res : printing.Showable if ! ctx.settings.YexplainLowlevel .value => res.show
1640- case _ => String .valueOf(res)
1641- }
1642-
16431650 override def isSubType (tp1 : Type , tp2 : Type ) =
16441651 traceIndented(s " ${show(tp1)} <:< ${show(tp2)}${if (Config .verboseExplainSubtype) s " ${tp1.getClass} ${tp2.getClass}" else " " }${if (frozenConstraint) " frozen" else " " }" ) {
16451652 super .isSubType(tp1, tp2)
0 commit comments