diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index 1d75c9ef0019..7083e457e577 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -210,7 +210,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling * types (as when we go from an abstract type to one of its bounds). In that case * one should use `isSubType(_, _, a)` where `a` defines the kind of approximation. * - * Note: Logicaly, `recur` could be nested in `isSubType`, which would avoid + * Note: Logically, `recur` could be nested in `isSubType`, which would avoid * the instance state consisting `approx` and `leftRoot`. But then the implemented * code would have two extra parameters for each of the many calls that go from * one sub-part of isSubType to another. @@ -2955,9 +2955,10 @@ class ExplainingTypeComparer(initctx: Context) extends TypeComparer(initctx) { if (skipped) op else { indent += 2 - b.append("\n").append(" " * indent).append("==> ").append(str) + val str1 = str.replace('\n', ' ') + b.append("\n").append(" " * indent).append("==> ").append(str1) val res = op - b.append("\n").append(" " * indent).append("<== ").append(str).append(" = ").append(show(res)) + b.append("\n").append(" " * indent).append("<== ").append(str1).append(" = ").append(show(res)) indent -= 2 res } @@ -2965,17 +2966,13 @@ class ExplainingTypeComparer(initctx: Context) extends TypeComparer(initctx) { private def frozenNotice: String = if frozenConstraint then " in frozen constraint" else "" - override def isSubType(tp1: Type, tp2: Type, approx: ApproxState): Boolean = + override def recur(tp1: Type, tp2: Type): Boolean = def moreInfo = if Config.verboseExplainSubtype || ctx.settings.verbose.value then s" ${tp1.getClass} ${tp2.getClass}" else "" + val approx = approxState traceIndented(s"${show(tp1)} <: ${show(tp2)}$moreInfo${approx.show}$frozenNotice") { - super.isSubType(tp1, tp2, approx) - } - - override def recur(tp1: Type, tp2: Type): Boolean = - traceIndented(s"${show(tp1)} <: ${show(tp2)} (recurring)$frozenNotice") { super.recur(tp1, tp2) } @@ -2995,7 +2992,7 @@ class ExplainingTypeComparer(initctx: Context) extends TypeComparer(initctx) { } override def addConstraint(param: TypeParamRef, bound: Type, fromBelow: Boolean)(using Context): Boolean = - traceIndented(i"add constraint $param ${if (fromBelow) ">:" else "<:"} $bound $frozenConstraint, constraint = ${ctx.typerState.constraint}") { + traceIndented(s"add constraint ${show(param)} ${if (fromBelow) ">:" else "<:"} ${show(bound)} $frozenNotice, constraint = ${show(ctx.typerState.constraint)}") { super.addConstraint(param, bound, fromBelow) } diff --git a/compiler/src/dotty/tools/dotc/reporting/trace.scala b/compiler/src/dotty/tools/dotc/reporting/trace.scala index 10179f9d3789..804188b20780 100644 --- a/compiler/src/dotty/tools/dotc/reporting/trace.scala +++ b/compiler/src/dotty/tools/dotc/reporting/trace.scala @@ -76,7 +76,7 @@ trait TraceSyntax: else // Avoid evaluating question multiple time, since each evaluation // may cause some extra logging output. - val q = question + val q = question.replace('\n', ' ') val leading = s"==> $q?" val trailing = (res: T) => s"<== $q = ${showOp(res)}" var finalized = false diff --git a/tests/neg-custom-args/i11637.check b/tests/neg-custom-args/i11637.check index 0f296927795e..eca2cf91b99f 100644 --- a/tests/neg-custom-args/i11637.check +++ b/tests/neg-custom-args/i11637.check @@ -13,26 +13,16 @@ conforms to but the comparison trace ended with `false`: ==> test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any - ==> test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any (recurring) - ==> type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] - ==> type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] (recurring) - ==> [T <: String] =>> Set[T] <: Iterable - ==> [T <: String] =>> Set[T] <: Iterable (recurring) - ==> type bounds [] <: type bounds [ <: String] - ==> type bounds [] <: type bounds [ <: String] (recurring) - ==> Any <: String - ==> Any <: String (recurring) - ==> Any <: String (recurring) - <== Any <: String (recurring) = false - <== Any <: String (recurring) = false - <== Any <: String = false - <== type bounds [] <: type bounds [ <: String] (recurring) = false - <== type bounds [] <: type bounds [ <: String] = false - <== [T <: String] =>> Set[T] <: Iterable (recurring) = false - <== [T <: String] =>> Set[T] <: Iterable = false - <== type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] (recurring) = false - <== type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] = false - <== test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any (recurring) = false + ==> type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] + ==> [T <: String] =>> Set[T] <: Iterable + ==> type bounds [] <: type bounds [ <: String] + ==> Any <: String + ==> Any <: String + <== Any <: String = false + <== Any <: String = false + <== type bounds [] <: type bounds [ <: String] = false + <== [T <: String] =>> Set[T] <: Iterable = false + <== type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] = false <== test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any = false The tests were made under the empty constraint @@ -52,26 +42,16 @@ conforms to but the comparison trace ended with `false`: ==> test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any - ==> test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any (recurring) - ==> type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] - ==> type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] (recurring) - ==> [T <: String] =>> Set[T] <: Iterable - ==> [T <: String] =>> Set[T] <: Iterable (recurring) - ==> type bounds [] <: type bounds [ <: String] - ==> type bounds [] <: type bounds [ <: String] (recurring) - ==> Any <: String - ==> Any <: String (recurring) - ==> Any <: String (recurring) - <== Any <: String (recurring) = false - <== Any <: String (recurring) = false - <== Any <: String = false - <== type bounds [] <: type bounds [ <: String] (recurring) = false - <== type bounds [] <: type bounds [ <: String] = false - <== [T <: String] =>> Set[T] <: Iterable (recurring) = false - <== [T <: String] =>> Set[T] <: Iterable = false - <== type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] (recurring) = false - <== type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] = false - <== test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any (recurring) = false + ==> type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] + ==> [T <: String] =>> Set[T] <: Iterable + ==> type bounds [] <: type bounds [ <: String] + ==> Any <: String + ==> Any <: String + <== Any <: String = false + <== Any <: String = false + <== type bounds [] <: type bounds [ <: String] = false + <== [T <: String] =>> Set[T] <: Iterable = false + <== type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] = false <== test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any = false The tests were made under the empty constraint