From 7973062a09b2c8c14ced8345600c186d61a600d8 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 21 Sep 2022 14:41:12 +0100 Subject: [PATCH 1/2] Give GadtConstraint a nicer toText Instead of showing the underlying constraint info, which just looks bad, takes up lots of space, and shows details that aren't relevant and often includes leaked type constructors, just show the symbols and their full bounds, nice and compact. And do that as a part of toText instead of having a side "debugBoundsDescription" alternative. --- .../tools/dotc/core/GadtConstraint.scala | 20 +++---------------- .../dotc/core/PatternTypeConstrainer.scala | 2 +- .../dotty/tools/dotc/core/TypeComparer.scala | 2 +- .../tools/dotc/printing/PlainPrinter.scala | 8 ++++++++ .../dotty/tools/dotc/printing/Printer.scala | 3 +++ 5 files changed, 16 insertions(+), 19 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/GadtConstraint.scala b/compiler/src/dotty/tools/dotc/core/GadtConstraint.scala index d8e1c5276ab6..a5f267173834 100644 --- a/compiler/src/dotty/tools/dotc/core/GadtConstraint.scala +++ b/compiler/src/dotty/tools/dotc/core/GadtConstraint.scala @@ -55,8 +55,6 @@ sealed abstract class GadtConstraint extends Showable { /** Restore the state from other [[GadtConstraint]], probably copied using [[fresh]] */ def restore(other: GadtConstraint): Unit - - def debugBoundsDescription(using Context): String } final class ProperGadtConstraint private( @@ -134,7 +132,7 @@ final class ProperGadtConstraint private( // The replaced symbols are picked up here. addToConstraint(poly1, tvars) - .showing(i"added to constraint: [$poly1] $params%, %\n$debugBoundsDescription", gadts) + .showing(i"added to constraint: [$poly1] $params%, % gadt = $this", gadts) } override def addBound(sym: Symbol, bound: Type, isUpper: Boolean)(using Context): Boolean = { @@ -291,17 +289,7 @@ final class ProperGadtConstraint private( override def constr = gadtsConstr - override def toText(printer: Printer): Texts.Text = constraint.toText(printer) - - override def debugBoundsDescription(using Context): String = { - val sb = new mutable.StringBuilder - sb ++= constraint.show - sb += '\n' - mapping.foreachBinding { case (sym, _) => - sb ++= i"$sym: ${fullBounds(sym)}\n" - } - sb.result - } + override def toText(printer: Printer): Texts.Text = printer.toText(this) } @sharable object EmptyGadtConstraint extends GadtConstraint { @@ -325,7 +313,5 @@ final class ProperGadtConstraint private( override def restore(other: GadtConstraint): Unit = assert(!other.isNarrowing, "cannot restore a non-empty GADTMap") - override def debugBoundsDescription(using Context): String = "EmptyGadtConstraint" - - override def toText(printer: Printer): Texts.Text = "EmptyGadtConstraint" + override def toText(printer: Printer): Texts.Text = printer.toText(this) } diff --git a/compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala b/compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala index c5f126580df5..ff9a5cd0aed7 100644 --- a/compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala +++ b/compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala @@ -261,7 +261,7 @@ trait PatternTypeConstrainer { self: TypeComparer => val assumeInvariantRefinement = migrateTo3 || forceInvariantRefinement || refinementIsInvariant(patternTp) - trace(i"constraining simple pattern type $tp >:< $pt", gadts, res => s"$res\ngadt = ${ctx.gadt.debugBoundsDescription}") { + trace(i"constraining simple pattern type $tp >:< $pt", gadts, (res: Boolean) => i"$res gadt = ${ctx.gadt}") { (tp, pt) match { case (AppliedType(tyconS, argsS), AppliedType(tyconP, argsP)) => val saved = state.nn.constraint diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index adce363dc3f4..9e946f430edc 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -3226,7 +3226,7 @@ class ExplainingTypeComparer(initctx: Context) extends TypeComparer(initctx) { } override def gadtAddBound(sym: Symbol, b: Type, isUpper: Boolean): Boolean = - traceIndented(s"add GADT constraint ${show(sym)} ${if isUpper then "<:" else ">:"} ${show(b)} $frozenNotice, GADT constraint = ${show(ctx.gadt.debugBoundsDescription)}") { + traceIndented(s"add GADT constraint ${show(sym)} ${if isUpper then "<:" else ">:"} ${show(b)} $frozenNotice, GADT constraint = ${show(ctx.gadt)}") { super.gadtAddBound(sym, b, isUpper) } diff --git a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala index d62b7afef707..b428a117d6a6 100644 --- a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala @@ -693,6 +693,14 @@ class PlainPrinter(_ctx: Context) extends Printer { finally ctx.typerState.constraint = savedConstraint + def toText(g: GadtConstraint): Text = g match + case EmptyGadtConstraint => "EmptyGadtConstraint" + case g: ProperGadtConstraint => + val deps = for sym <- g.symbols yield + val bound = g.fullBounds(sym).nn + (typeText(toText(sym.typeRef)) ~ toText(bound)).close + ("GadtConstraint(" ~ Text(deps, ", ") ~ ")").close + def plain: PlainPrinter = this protected def keywordStr(text: String): String = coloredStr(text, SyntaxHighlighting.KeywordColor) diff --git a/compiler/src/dotty/tools/dotc/printing/Printer.scala b/compiler/src/dotty/tools/dotc/printing/Printer.scala index b883b6be805b..f06c70f56905 100644 --- a/compiler/src/dotty/tools/dotc/printing/Printer.scala +++ b/compiler/src/dotty/tools/dotc/printing/Printer.scala @@ -163,6 +163,9 @@ abstract class Printer { /** Textual representation of a constraint */ def toText(c: OrderingConstraint): Text + /** Textual representation of a GADT constraint */ + def toText(c: GadtConstraint): Text + /** Render element within highest precedence */ def toTextLocal(elem: Showable): Text = atPrec(DotPrec) { elem.toText(this) } From 1094cbe82f083db4d6518c5c07f38b99d08762fc Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 3 Oct 2022 09:03:36 +0100 Subject: [PATCH 2/2] Keep debugBoundsDescription to view the underlying constraint --- compiler/src/dotty/tools/dotc/core/GadtConstraint.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compiler/src/dotty/tools/dotc/core/GadtConstraint.scala b/compiler/src/dotty/tools/dotc/core/GadtConstraint.scala index a5f267173834..f3a5e740e07c 100644 --- a/compiler/src/dotty/tools/dotc/core/GadtConstraint.scala +++ b/compiler/src/dotty/tools/dotc/core/GadtConstraint.scala @@ -55,6 +55,9 @@ sealed abstract class GadtConstraint extends Showable { /** Restore the state from other [[GadtConstraint]], probably copied using [[fresh]] */ def restore(other: GadtConstraint): Unit + + /** Provides more information than toText, by showing the underlying Constraint details. */ + def debugBoundsDescription(using Context): String } final class ProperGadtConstraint private( @@ -290,6 +293,8 @@ final class ProperGadtConstraint private( override def constr = gadtsConstr override def toText(printer: Printer): Texts.Text = printer.toText(this) + + override def debugBoundsDescription(using Context): String = i"$this\n$constraint" } @sharable object EmptyGadtConstraint extends GadtConstraint { @@ -314,4 +319,5 @@ final class ProperGadtConstraint private( assert(!other.isNarrowing, "cannot restore a non-empty GADTMap") override def toText(printer: Printer): Texts.Text = printer.toText(this) + override def debugBoundsDescription(using Context): String = i"$this" }