@@ -253,7 +253,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
253253 // }
254254 assert(! ctx.settings.YnoDeepSubtypes .value)
255255 if (Config .traceDeepSubTypeRecursions && ! this .isInstanceOf [ExplainingTypeComparer ])
256- report.log(explained(_.isSubType(tp1, tp2, approx)))
256+ report.log(explained(_.isSubType(tp1, tp2, approx), short = false ))
257257 }
258258 // Eliminate LazyRefs before checking whether we have seen a type before
259259 val normalize = new TypeMap with CaptureSet .IdempotentCaptRefMap {
@@ -2959,7 +2959,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
29592959 }
29602960 }
29612961
2962- protected def explainingTypeComparer = ExplainingTypeComparer (comparerContext)
2962+ protected def explainingTypeComparer ( short : Boolean ) = ExplainingTypeComparer (comparerContext, short )
29632963 protected def trackingTypeComparer = TrackingTypeComparer (comparerContext)
29642964
29652965 private def inSubComparer [T , Cmp <: TypeComparer ](comparer : Cmp )(op : Cmp => T ): T =
@@ -2969,8 +2969,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
29692969 finally myInstance = saved
29702970
29712971 /** The trace of comparison operations when performing `op` */
2972- def explained [T ](op : ExplainingTypeComparer => T , header : String = " Subtype trace:" )(using Context ): String =
2973- val cmp = explainingTypeComparer
2972+ def explained [T ](op : ExplainingTypeComparer => T , header : String = " Subtype trace:" , short : Boolean )(using Context ): String =
2973+ val cmp = explainingTypeComparer(short)
29742974 inSubComparer(cmp)(op)
29752975 cmp.lastTrace(header)
29762976
@@ -3139,8 +3139,8 @@ object TypeComparer {
31393139 def constrainPatternType (pat : Type , scrut : Type , forceInvariantRefinement : Boolean = false )(using Context ): Boolean =
31403140 comparing(_.constrainPatternType(pat, scrut, forceInvariantRefinement))
31413141
3142- def explained [T ](op : ExplainingTypeComparer => T , header : String = " Subtype trace:" )(using Context ): String =
3143- comparing(_.explained(op, header))
3142+ def explained [T ](op : ExplainingTypeComparer => T , header : String = " Subtype trace:" , short : Boolean = false )(using Context ): String =
3143+ comparing(_.explained(op, header, short ))
31443144
31453145 def tracked [T ](op : TrackingTypeComparer => T )(using Context ): T =
31463146 comparing(_.tracked(op))
@@ -3337,30 +3337,47 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
33373337 }
33383338}
33393339
3340- /** A type comparer that can record traces of subtype operations */
3341- class ExplainingTypeComparer (initctx : Context ) extends TypeComparer (initctx) {
3340+ /** A type comparer that can record traces of subtype operations
3341+ * @param short if true print only failing forward traces; never print succesful
3342+ * subtraces; never print backtraces starting with `<==`.
3343+ */
3344+ class ExplainingTypeComparer (initctx : Context , short : Boolean ) extends TypeComparer (initctx) {
33423345 import TypeComparer ._
33433346
33443347 init(initctx)
33453348
3346- override def explainingTypeComparer = this
3349+ override def explainingTypeComparer (short : Boolean ) =
3350+ if short == this .short then this
3351+ else ExplainingTypeComparer (comparerContext, short)
33473352
33483353 private var indent = 0
33493354 private val b = new StringBuilder
3350-
3351- private var skipped = false
3355+ private var lastForwardGoal : String | Null = null
33523356
33533357 override def traceIndented [T ](str : String )(op : => T ): T =
3354- if (skipped) op
3355- else {
3358+ val str1 = str.replace('\n ' , ' ' )
3359+ if short && str1 == lastForwardGoal then
3360+ op // repeated goal, skip for clarity
3361+ else
3362+ lastForwardGoal = str1
3363+ val curLength = b.length
33563364 indent += 2
3357- val str1 = str.replace('\n ' , ' ' )
33583365 b.append(" \n " ).append(" " * indent).append(" ==> " ).append(str1)
33593366 val res = op
3360- b.append(" \n " ).append(" " * indent).append(" <== " ).append(str1).append(" = " ).append(show(res))
3367+ if short then
3368+ if res == false then
3369+ if lastForwardGoal != null then // last was deepest goal that failed
3370+ b.append(" = false" )
3371+ lastForwardGoal = null
3372+ else
3373+ b.length = curLength // don't show successful subtraces
3374+ else
3375+ b.append(" \n " ).append(" " * indent).append(" <== " ).append(str1).append(" = " ).append(show(res))
33613376 indent -= 2
33623377 res
3363- }
3378+
3379+ private def traceIndentedIfNotShort [T ](str : String )(op : => T ): T =
3380+ if short then op else traceIndented(str)(op)
33643381
33653382 private def frozenNotice : String =
33663383 if frozenConstraint then " in frozen constraint" else " "
@@ -3371,7 +3388,8 @@ class ExplainingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
33713388 then s " ${tp1.getClass} ${tp2.getClass}"
33723389 else " "
33733390 val approx = approxState
3374- traceIndented(s " ${show(tp1)} <: ${show(tp2)}$moreInfo${approx.show}$frozenNotice" ) {
3391+ def approxStr = if short then " " else approx.show
3392+ traceIndented(s " ${show(tp1)} <: ${show(tp2)}$moreInfo${approxStr}$frozenNotice" ) {
33753393 super .recur(tp1, tp2)
33763394 }
33773395
@@ -3381,12 +3399,12 @@ class ExplainingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
33813399 }
33823400
33833401 override def lub (tp1 : Type , tp2 : Type , canConstrain : Boolean , isSoft : Boolean ): Type =
3384- traceIndented (s " lub( ${show(tp1)}, ${show(tp2)}, canConstrain= $canConstrain, isSoft= $isSoft) " ) {
3402+ traceIndentedIfNotShort (s " lub( ${show(tp1)}, ${show(tp2)}, canConstrain= $canConstrain, isSoft= $isSoft) " ) {
33853403 super .lub(tp1, tp2, canConstrain, isSoft)
33863404 }
33873405
33883406 override def glb (tp1 : Type , tp2 : Type ): Type =
3389- traceIndented (s " glb( ${show(tp1)}, ${show(tp2)}) " ) {
3407+ traceIndentedIfNotShort (s " glb( ${show(tp1)}, ${show(tp2)}) " ) {
33903408 super .glb(tp1, tp2)
33913409 }
33923410
0 commit comments