@@ -253,7 +253,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
253
253
// }
254
254
assert(! ctx.settings.YnoDeepSubtypes .value)
255
255
if (Config .traceDeepSubTypeRecursions && ! this .isInstanceOf [ExplainingTypeComparer ])
256
- report.log(explained(_.isSubType(tp1, tp2, approx)))
256
+ report.log(explained(_.isSubType(tp1, tp2, approx), short = false ))
257
257
}
258
258
// Eliminate LazyRefs before checking whether we have seen a type before
259
259
val normalize = new TypeMap with CaptureSet .IdempotentCaptRefMap {
@@ -2959,7 +2959,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2959
2959
}
2960
2960
}
2961
2961
2962
- protected def explainingTypeComparer = ExplainingTypeComparer (comparerContext)
2962
+ protected def explainingTypeComparer ( short : Boolean ) = ExplainingTypeComparer (comparerContext, short )
2963
2963
protected def trackingTypeComparer = TrackingTypeComparer (comparerContext)
2964
2964
2965
2965
private def inSubComparer [T , Cmp <: TypeComparer ](comparer : Cmp )(op : Cmp => T ): T =
@@ -2969,8 +2969,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2969
2969
finally myInstance = saved
2970
2970
2971
2971
/** 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)
2974
2974
inSubComparer(cmp)(op)
2975
2975
cmp.lastTrace(header)
2976
2976
@@ -3139,8 +3139,8 @@ object TypeComparer {
3139
3139
def constrainPatternType (pat : Type , scrut : Type , forceInvariantRefinement : Boolean = false )(using Context ): Boolean =
3140
3140
comparing(_.constrainPatternType(pat, scrut, forceInvariantRefinement))
3141
3141
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 ))
3144
3144
3145
3145
def tracked [T ](op : TrackingTypeComparer => T )(using Context ): T =
3146
3146
comparing(_.tracked(op))
@@ -3337,30 +3337,47 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
3337
3337
}
3338
3338
}
3339
3339
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) {
3342
3345
import TypeComparer ._
3343
3346
3344
3347
init(initctx)
3345
3348
3346
- override def explainingTypeComparer = this
3349
+ override def explainingTypeComparer (short : Boolean ) =
3350
+ if short == this .short then this
3351
+ else ExplainingTypeComparer (comparerContext, short)
3347
3352
3348
3353
private var indent = 0
3349
3354
private val b = new StringBuilder
3350
-
3351
- private var skipped = false
3355
+ private var lastForwardGoal : String | Null = null
3352
3356
3353
3357
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
3356
3364
indent += 2
3357
- val str1 = str.replace('\n ' , ' ' )
3358
3365
b.append(" \n " ).append(" " * indent).append(" ==> " ).append(str1)
3359
3366
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))
3361
3376
indent -= 2
3362
3377
res
3363
- }
3378
+
3379
+ private def traceIndentedIfNotShort [T ](str : String )(op : => T ): T =
3380
+ if short then op else traceIndented(str)(op)
3364
3381
3365
3382
private def frozenNotice : String =
3366
3383
if frozenConstraint then " in frozen constraint" else " "
@@ -3371,7 +3388,8 @@ class ExplainingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
3371
3388
then s " ${tp1.getClass} ${tp2.getClass}"
3372
3389
else " "
3373
3390
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" ) {
3375
3393
super .recur(tp1, tp2)
3376
3394
}
3377
3395
@@ -3381,12 +3399,12 @@ class ExplainingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
3381
3399
}
3382
3400
3383
3401
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) " ) {
3385
3403
super .lub(tp1, tp2, canConstrain, isSoft)
3386
3404
}
3387
3405
3388
3406
override def glb (tp1 : Type , tp2 : Type ): Type =
3389
- traceIndented (s " glb( ${show(tp1)}, ${show(tp2)}) " ) {
3407
+ traceIndentedIfNotShort (s " glb( ${show(tp1)}, ${show(tp2)}) " ) {
3390
3408
super .glb(tp1, tp2)
3391
3409
}
3392
3410
0 commit comments