Skip to content

Commit df16731

Browse files
committed
Avoid assertion failure when forcing LazyRef while printing
Fixes #12650 The fix that matters for #12650 is the one in Checking. The others generally increase robustness of printing diagnostics when triggering a LazyRef recursion.
1 parent 56abade commit df16731

File tree

6 files changed

+30
-18
lines changed

6 files changed

+30
-18
lines changed

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

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2396,19 +2396,21 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
23962396
}
23972397

23982398
/** Show subtype goal that led to an assertion failure */
2399-
def showGoal(tp1: Type, tp2: Type)(using Context): Unit = {
2400-
report.echo(i"assertion failure for ${show(tp1)} <:< ${show(tp2)}, frozen = $frozenConstraint")
2401-
def explainPoly(tp: Type) = tp match {
2402-
case tp: TypeParamRef => report.echo(s"TypeParamRef ${tp.show} found in ${tp.binder.show}")
2403-
case tp: TypeRef if tp.symbol.exists => report.echo(s"typeref ${tp.show} found in ${tp.symbol.owner.show}")
2404-
case tp: TypeVar => report.echo(s"typevar ${tp.show}, origin = ${tp.origin}")
2405-
case _ => report.echo(s"${tp.show} is a ${tp.getClass}")
2406-
}
2407-
if (Config.verboseExplainSubtype) {
2408-
explainPoly(tp1)
2409-
explainPoly(tp2)
2410-
}
2411-
}
2399+
def showGoal(tp1: Type, tp2: Type)(using Context): Unit =
2400+
try
2401+
report.echo(i"assertion failure for ${show(tp1)} <:< ${show(tp2)}, frozen = $frozenConstraint")
2402+
def explainPoly(tp: Type) = tp match {
2403+
case tp: TypeParamRef => report.echo(s"TypeParamRef ${tp.show} found in ${tp.binder.show}")
2404+
case tp: TypeRef if tp.symbol.exists => report.echo(s"typeref ${tp.show} found in ${tp.symbol.owner.show}")
2405+
case tp: TypeVar => report.echo(s"typevar ${tp.show}, origin = ${tp.origin}")
2406+
case _ => report.echo(s"${tp.show} is a ${tp.getClass}")
2407+
}
2408+
if (Config.verboseExplainSubtype) {
2409+
explainPoly(tp1)
2410+
explainPoly(tp2)
2411+
}
2412+
catch case NonFatal(ex) =>
2413+
report.echo(s"assertion failure [[cannot display since $ex was thrown]]")
24122414

24132415
/** Record statistics about the total number of subtype checks
24142416
* and the number of "successful" subtype checks, i.e. checks

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2833,7 +2833,9 @@ object Types {
28332833
if myRef == null then
28342834
// if errors were reported previously handle this by throwing a CyclicReference
28352835
// instead of crashing immediately. A test case is neg/i6057.scala.
2836-
assert(ctx.mode.is(Mode.CheckCyclic) || ctx.reporter.errorsReported)
2836+
assert(ctx.mode.is(Mode.CheckCyclic)
2837+
|| ctx.mode.is(Mode.Printing)
2838+
|| ctx.reporter.errorsReported)
28372839
throw CyclicReference(NoDenotation)
28382840
else
28392841
computed = true

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -403,11 +403,11 @@ object Checking {
403403
return
404404

405405
def qualifies(sym: Symbol) = sym.name.isTypeName && !sym.is(Private)
406-
val abstractTypeNames =
407-
for (parent <- parents; mbr <- parent.abstractTypeMembers if qualifies(mbr.symbol))
408-
yield mbr.name.asTypeName
409-
410406
withMode(Mode.CheckCyclic) {
407+
val abstractTypeNames =
408+
for (parent <- parents; mbr <- parent.abstractTypeMembers if qualifies(mbr.symbol))
409+
yield mbr.name.asTypeName
410+
411411
for name <- abstractTypeNames do
412412
try
413413
val mbr = joint.member(name)

compiler/test/dotty/tools/dotc/CompilationTests.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ class CompilationTests {
147147
compileFile("tests/neg-custom-args/i3882.scala", allowDeepSubtypes),
148148
compileFile("tests/neg-custom-args/i4372.scala", allowDeepSubtypes),
149149
compileFile("tests/neg-custom-args/i1754.scala", allowDeepSubtypes),
150+
compileFile("tests/neg-custom-args/i12650.scala", allowDeepSubtypes),
150151
compileFile("tests/neg-custom-args/i9517.scala", defaultOptions.and("-Xprint-types")),
151152
compileFile("tests/neg-custom-args/i11637.scala", defaultOptions.and("-explain")),
152153
compileFile("tests/neg-custom-args/interop-polytypes.scala", allowDeepSubtypes.and("-Yexplicit-nulls")),

tests/neg-custom-args/i12650.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-- Error: tests/neg-custom-args/i12650.scala:2:58 ----------------------------------------------------------------------
2+
2 | type This <: FooBase { type This <: FooBase.this.This } & FooBase { type This <: FooBase.this.This } // error
3+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4+
| cyclic reference involving type This

tests/neg-custom-args/i12650.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
trait FooBase {
2+
type This <: FooBase { type This <: FooBase.this.This } & FooBase { type This <: FooBase.this.This } // error
3+
}

0 commit comments

Comments
 (0)