@@ -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 {
@@ -2972,7 +2972,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
29722972 }
29732973 }
29742974
2975- protected def explainingTypeComparer = ExplainingTypeComparer (comparerContext)
2975+ protected def explainingTypeComparer ( short : Boolean ) = ExplainingTypeComparer (comparerContext, short )
29762976 protected def trackingTypeComparer = TrackingTypeComparer (comparerContext)
29772977
29782978 private def inSubComparer [T , Cmp <: TypeComparer ](comparer : Cmp )(op : Cmp => T ): T =
@@ -2982,8 +2982,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
29822982 finally myInstance = saved
29832983
29842984 /** The trace of comparison operations when performing `op` */
2985- def explained [T ](op : ExplainingTypeComparer => T , header : String = " Subtype trace:" )(using Context ): String =
2986- val cmp = explainingTypeComparer
2985+ def explained [T ](op : ExplainingTypeComparer => T , header : String = " Subtype trace:" , short : Boolean )(using Context ): String =
2986+ val cmp = explainingTypeComparer(short)
29872987 inSubComparer(cmp)(op)
29882988 cmp.lastTrace(header)
29892989
@@ -3152,8 +3152,8 @@ object TypeComparer {
31523152 def constrainPatternType (pat : Type , scrut : Type , forceInvariantRefinement : Boolean = false )(using Context ): Boolean =
31533153 comparing(_.constrainPatternType(pat, scrut, forceInvariantRefinement))
31543154
3155- def explained [T ](op : ExplainingTypeComparer => T , header : String = " Subtype trace:" )(using Context ): String =
3156- comparing(_.explained(op, header))
3155+ def explained [T ](op : ExplainingTypeComparer => T , header : String = " Subtype trace:" , short : Boolean = false )(using Context ): String =
3156+ comparing(_.explained(op, header, short ))
31573157
31583158 def tracked [T ](op : TrackingTypeComparer => T )(using Context ): T =
31593159 comparing(_.tracked(op))
@@ -3350,30 +3350,47 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
33503350 }
33513351}
33523352
3353- /** A type comparer that can record traces of subtype operations */
3354- class ExplainingTypeComparer (initctx : Context ) extends TypeComparer (initctx) {
3353+ /** A type comparer that can record traces of subtype operations
3354+ * @param short if true print only failing forward traces; never print succesful
3355+ * subtraces; never print backtraces starting with `<==`.
3356+ */
3357+ class ExplainingTypeComparer (initctx : Context , short : Boolean ) extends TypeComparer (initctx) {
33553358 import TypeComparer ._
33563359
33573360 init(initctx)
33583361
3359- override def explainingTypeComparer = this
3362+ override def explainingTypeComparer (short : Boolean ) =
3363+ if short == this .short then this
3364+ else ExplainingTypeComparer (comparerContext, short)
33603365
33613366 private var indent = 0
33623367 private val b = new StringBuilder
3363-
3364- private var skipped = false
3368+ private var lastForwardGoal : String | Null = null
33653369
33663370 override def traceIndented [T ](str : String )(op : => T ): T =
3367- if (skipped) op
3368- else {
3371+ val str1 = str.replace('\n ' , ' ' )
3372+ if short && str1 == lastForwardGoal then
3373+ op // repeated goal, skip for clarity
3374+ else
3375+ lastForwardGoal = str1
3376+ val curLength = b.length
33693377 indent += 2
3370- val str1 = str.replace('\n ' , ' ' )
33713378 b.append(" \n " ).append(" " * indent).append(" ==> " ).append(str1)
33723379 val res = op
3373- b.append(" \n " ).append(" " * indent).append(" <== " ).append(str1).append(" = " ).append(show(res))
3380+ if short then
3381+ if res == false then
3382+ if lastForwardGoal != null then // last was deepest goal that failed
3383+ b.append(" = false" )
3384+ lastForwardGoal = null
3385+ else
3386+ b.length = curLength // don't show successful subtraces
3387+ else
3388+ b.append(" \n " ).append(" " * indent).append(" <== " ).append(str1).append(" = " ).append(show(res))
33743389 indent -= 2
33753390 res
3376- }
3391+
3392+ private def traceIndentedIfNotShort [T ](str : String )(op : => T ): T =
3393+ if short then op else traceIndented(str)(op)
33773394
33783395 private def frozenNotice : String =
33793396 if frozenConstraint then " in frozen constraint" else " "
@@ -3384,7 +3401,8 @@ class ExplainingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
33843401 then s " ${tp1.getClass} ${tp2.getClass}"
33853402 else " "
33863403 val approx = approxState
3387- traceIndented(s " ${show(tp1)} <: ${show(tp2)}$moreInfo${approx.show}$frozenNotice" ) {
3404+ def approxStr = if short then " " else approx.show
3405+ traceIndented(s " ${show(tp1)} <: ${show(tp2)}$moreInfo${approxStr}$frozenNotice" ) {
33883406 super .recur(tp1, tp2)
33893407 }
33903408
@@ -3394,12 +3412,12 @@ class ExplainingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
33943412 }
33953413
33963414 override def lub (tp1 : Type , tp2 : Type , canConstrain : Boolean , isSoft : Boolean ): Type =
3397- traceIndented (s " lub( ${show(tp1)}, ${show(tp2)}, canConstrain= $canConstrain, isSoft= $isSoft) " ) {
3415+ traceIndentedIfNotShort (s " lub( ${show(tp1)}, ${show(tp2)}, canConstrain= $canConstrain, isSoft= $isSoft) " ) {
33983416 super .lub(tp1, tp2, canConstrain, isSoft)
33993417 }
34003418
34013419 override def glb (tp1 : Type , tp2 : Type ): Type =
3402- traceIndented (s " glb( ${show(tp1)}, ${show(tp2)}) " ) {
3420+ traceIndentedIfNotShort (s " glb( ${show(tp1)}, ${show(tp2)}) " ) {
34033421 super .glb(tp1, tp2)
34043422 }
34053423
0 commit comments