Skip to content

Commit f3ec774

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 1ee888a commit f3ec774

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 checkTypeRefCycle = 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
@@ -1514,7 +1514,14 @@ object Types {
15141514
}
15151515

15161516
/** Hook for adding debug check code when denotations are assigned */
1517-
final def checkDenot()(implicit ctx: Context) = {}
1517+
final def checkDenot()(implicit ctx: Context) =
1518+
if (Config.checkTypeRefCycles)
1519+
lastDenotation.info match {
1520+
case TypeBounds(lo, hi) =>
1521+
assert(lo.stripTypeVar.stripAnnots ne this)
1522+
assert(hi.stripTypeVar.stripAnnots ne this)
1523+
case _ =>
1524+
}
15181525

15191526
/** A second fallback to recompute the denotation if necessary */
15201527
private def computeDenot(implicit ctx: Context): Denotation = {
@@ -1548,9 +1555,9 @@ object Types {
15481555

15491556
// Don't use setDenot here; double binding checks can give spurious failures after erasure
15501557
lastDenotation = d
1551-
checkDenot()
15521558
lastSymbol = d.symbol
15531559
checkedPeriod = ctx.period
1560+
checkDenot()
15541561
}
15551562
d
15561563
}

0 commit comments

Comments
 (0)