Skip to content

Commit e7d3b92

Browse files
committed
Keep track of failure traces when subCapturing fails under -Ycc-debug
1 parent 6ae1a89 commit e7d3b92

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

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

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ object CaptureSet:
417417
def isAlwaysEmpty = elems.isEmpty
418418

419419
def addNewElem(elem: CaptureRef, origin: CaptureSet)(using Context, VarState): CompareResult =
420-
CompareResult.Fail(this)
420+
CompareResult.Fail(this :: Nil)
421421

422422
def addDependent(cs: CaptureSet)(using Context, VarState) = CompareResult.OK
423423

@@ -505,7 +505,7 @@ object CaptureSet:
505505

506506
final def addNewElem(elem: CaptureRef, origin: CaptureSet)(using Context, VarState): CompareResult =
507507
if isConst || !recordElemsState() then
508-
CompareResult.Fail(this) // fail if variable is solved or given VarState is frozen
508+
CompareResult.Fail(this :: Nil) // fail if variable is solved or given VarState is frozen
509509
else if !levelOK(elem) then
510510
val res = CompareResult.LevelError(this, elem)
511511
if elem.isRootCapability then res
@@ -518,7 +518,7 @@ object CaptureSet:
518518
// assert(id != 5 || elems.size != 3, this)
519519
(CompareResult.OK /: deps) { (r, dep) =>
520520
r.andAlso(dep.tryInclude(elem, this))
521-
}
521+
}.addToTrace(this)
522522

523523
private def levelOK(elem: CaptureRef)(using Context): Boolean =
524524
!levelLimit.exists
@@ -540,7 +540,7 @@ object CaptureSet:
540540
deps += cs
541541
CompareResult.OK
542542
else
543-
CompareResult.Fail(this)
543+
CompareResult.Fail(this :: Nil)
544544

545545
override def disallowRootCapability(handler: () => Context ?=> Unit)(using Context): this.type =
546546
rootAddedHandler = handler
@@ -684,7 +684,7 @@ object CaptureSet:
684684
.andAlso {
685685
if added.isConst then CompareResult.OK
686686
else if added.asVar.recordDepsState() then { addAsDependentTo(added); CompareResult.OK }
687-
else CompareResult.Fail(this)
687+
else CompareResult.Fail(this :: Nil)
688688
}
689689
.andAlso {
690690
if (origin ne source) && (origin ne initial) && mapIsIdempotent then
@@ -701,7 +701,7 @@ object CaptureSet:
701701
// we approximate types resulting from such maps by returning a possible super type
702702
// from the actual type. But this is neither sound nor complete.
703703
report.warning(em"trying to add elems ${CaptureSet(newElems)} from unrecognized source $origin of mapped set $this$whereCreated")
704-
CompareResult.Fail(this)
704+
CompareResult.Fail(this :: Nil)
705705
else
706706
CompareResult.OK
707707
}
@@ -767,7 +767,7 @@ object CaptureSet:
767767
super.addNewElems(newElems, origin)
768768
.andAlso {
769769
if filtered.size == newElems.size then source.tryInclude(newElems, this)
770-
else CompareResult.Fail(this)
770+
else CompareResult.Fail(this :: Nil)
771771
}
772772

773773
override def computeApprox(origin: CaptureSet)(using Context): CaptureSet =
@@ -866,14 +866,16 @@ object CaptureSet:
866866

867867
enum CompareResult extends Showable:
868868
case OK
869-
case Fail(cs: CaptureSet)
869+
case Fail(trace: List[CaptureSet])
870870
case LevelError(cs: CaptureSet, elem: CaptureRef)
871871

872872
override def toText(printer: Printer): Text =
873873
inContext(printer.printerContext):
874874
this match
875875
case OK => Str("OK")
876-
case Fail(blocking: CaptureSet) => blocking.show
876+
case Fail(trace) =>
877+
if ctx.settings.YccDebug.value then printer.toText(trace, ", ")
878+
else blocking.show
877879
case LevelError(cs: CaptureSet, elem: CaptureRef) =>
878880
Str(i"($elem at wrong level for $cs in ${cs.levelLimit})")
879881

@@ -882,7 +884,7 @@ object CaptureSet:
882884

883885
/** If not isOK, the blocking capture set */
884886
def blocking: CaptureSet = (this: @unchecked) match
885-
case Fail(cs) => cs
887+
case Fail(cs) => cs.last
886888
case LevelError(cs, _) => cs
887889

888890
/** Optionally, this result if it is a level error */
@@ -899,6 +901,10 @@ object CaptureSet:
899901
val alt = op
900902
if alt.isOK then alt
901903
else this
904+
905+
inline def addToTrace(cs: CaptureSet) = this match
906+
case Fail(trace) => Fail(cs :: trace)
907+
case _ => this
902908
end CompareResult
903909

904910
/** A VarState serves as a snapshot mechanism that can undo

0 commit comments

Comments
 (0)