Skip to content

Commit 674333a

Browse files
committed
Detect direct cycles of typerefs referring to themselves
Have a Config option that allows to flag as assertion errors typerefs that refer directly to themselves in a bound or alias. I am going to use this to track down isRef stackoverflows; I believe it is also useful to keep around in case similar errors appear later.
1 parent 0734ce9 commit 674333a

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

compiler/src/dotty/tools/dotc/config/Config.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ object Config {
108108
*/
109109
final val checkMethodTypes = false
110110

111+
/** If this flag is set, it is checked that TypeRefs don't refer directly
112+
* to themselves.
113+
*/
114+
final val checkTypeRefCycles = true
115+
111116
/** The recursion depth for showing a summarized string */
112117
final val summarizeDepth = 2
113118

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,7 +1526,14 @@ object Types {
15261526
}
15271527

15281528
/** Hook for adding debug check code when denotations are assigned */
1529-
final def checkDenot()(implicit ctx: Context) = {}
1529+
final def checkDenot()(implicit ctx: Context) =
1530+
if (Config.checkTypeRefCycles)
1531+
lastDenotation.info match {
1532+
case TypeBounds(lo, hi) =>
1533+
assert(lo.stripTypeVar.stripAnnots ne this)
1534+
assert(hi.stripTypeVar.stripAnnots ne this)
1535+
case _ =>
1536+
}
15301537

15311538
/** A second fallback to recompute the denotation if necessary */
15321539
private def computeDenot(implicit ctx: Context): Denotation = {
@@ -1562,9 +1569,9 @@ object Types {
15621569

15631570
// Don't use setDenot here; double binding checks can give spurious failures after erasure
15641571
lastDenotation = d
1565-
checkDenot()
15661572
lastSymbol = d.symbol
15671573
checkedPeriod = ctx.period
1574+
checkDenot()
15681575
}
15691576
d
15701577
}

0 commit comments

Comments
 (0)