Skip to content

Commit cecf206

Browse files
committed
Print capture variable dependencies under -Ydebug-cc
1 parent 1e69251 commit cecf206

File tree

2 files changed

+41
-5
lines changed

2 files changed

+41
-5
lines changed

compiler/src/dotty/tools/dotc/cc/CaptureSet.scala

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ import annotation.internal.sharable
1212
import reporting.trace
1313
import printing.{Showable, Printer}
1414
import printing.Texts.*
15-
import util.SimpleIdentitySet
15+
import util.{SimpleIdentitySet, Property}
1616
import util.common.alwaysTrue
17+
import scala.collection.mutable
1718

1819
/** A class for capture sets. Capture sets can be constants or variables.
1920
* Capture sets support inclusion constraints <:< where <:< is subcapturing.
@@ -317,6 +318,7 @@ object CaptureSet:
317318
s"$id${getClass.getSimpleName.take(1)}$trail"
318319

319320
override def toText(printer: Printer): Text = inContext(printer.printerContext) {
321+
for vars <- ctx.property(ShownVars) do vars += this
320322
super.toText(printer) ~ (Str(ids) provided !isConst && ctx.settings.YccDebug.value)
321323
}
322324

@@ -528,4 +530,34 @@ object CaptureSet:
528530
empty
529531
recur(tp)
530532
.showing(i"capture set of $tp = $result", capt)
533+
534+
private val ShownVars: Property.Key[mutable.Set[Var]] = Property.Key()
535+
536+
def withCaptureSetsExplained[T](op: Context ?=> T)(using ctx: Context): T =
537+
if ctx.settings.YccDebug.value then
538+
val shownVars = mutable.Set[Var]()
539+
inContext(ctx.withProperty(ShownVars, Some(shownVars))) {
540+
try op
541+
finally
542+
val reachable = mutable.Set[Var]()
543+
val todo = mutable.Queue[Var]() ++= shownVars
544+
def incl(cv: Var): Unit =
545+
if !reachable.contains(cv) then todo += cv
546+
while todo.nonEmpty do
547+
val cv = todo.dequeue()
548+
if !reachable.contains(cv) then
549+
reachable += cv
550+
cv.deps.foreach {
551+
case cv: Var => incl(cv)
552+
case _ =>
553+
}
554+
cv match
555+
case cv: DerivedVar => incl(cv.source)
556+
case _ =>
557+
val allVars = reachable.toArray.sortBy(_.id)
558+
println(i"Capture set dependencies:")
559+
for cv <- allVars do
560+
println(i" ${cv.show.padTo(20, ' ')} :: ${cv.deps.toList}%, %")
561+
}
562+
else op
531563
end CaptureSet

compiler/src/dotty/tools/dotc/typer/CheckCaptures.scala

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ import Trees._
1616
import scala.util.control.NonFatal
1717
import typer.ErrorReporting._
1818
import util.Spans.Span
19-
import util.{SimpleIdentitySet, EqHashMap, SrcPos, Property}
19+
import util.{SimpleIdentitySet, EqHashMap, SrcPos}
2020
import util.Chars.*
2121
import transform.*
2222
import transform.SymUtils.*
2323
import scala.collection.mutable
2424
import reporting._
2525
import dotty.tools.backend.jvm.DottyBackendInterface.symExtensions
26-
import CaptureSet.CompareResult
26+
import CaptureSet.{CompareResult, withCaptureSetsExplained}
2727

2828
object CheckCaptures:
2929
import ast.tpd.*
@@ -359,8 +359,12 @@ class CheckCaptures extends Recheck:
359359
res
360360

361361
override def checkUnit(unit: CompilationUnit)(using Context): Unit =
362-
super.checkUnit(unit)
363-
PostRefinerCheck.traverse(unit.tpdTree)
362+
withCaptureSetsExplained {
363+
super.checkUnit(unit)
364+
PostRefinerCheck.traverse(unit.tpdTree)
365+
if ctx.settings.YccDebug.value then
366+
show(unit.tpdTree) // this dows not print tree, but makes its variables visible for dependency printing
367+
}
364368

365369
def checkNotGlobal(tree: Tree, allArgs: Tree*)(using Context): Unit =
366370
if disallowGlobal then

0 commit comments

Comments
 (0)