From e92dd4d893ccd4e365dd8d06066cec65e47896a9 Mon Sep 17 00:00:00 2001 From: odersky Date: Sat, 19 Nov 2022 13:06:21 +0100 Subject: [PATCH] Avoid stackoverflow in ExplicitOuter When transforming a class at ExplicitOuter we create outer accessors for it. The newSymbol call to do this takes place at phase ExplicitOuter + 1, but its arguments need to be evaluated at phase ExplicitOuter. This was not true for the nestingLevel argument, which demanded the denotation of the class at phase ExplicitOuter + 1, thus leading to the SO. Interestingly, the same path is not taken if the class has all abstract members defined or is declared abstract. It's only in the error case that I could reproduce the SO. --- compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala | 3 ++- tests/neg/i16343.scala | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 tests/neg/i16343.scala diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala index 00074a6ea81a..c1536022a2ac 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -176,8 +176,9 @@ object ExplicitOuter { if prefix == NoPrefix then outerCls.typeRef.appliedTo(outerCls.typeParams.map(_ => TypeBounds.empty)) else prefix.widen) val info = if (flags.is(Method)) ExprType(target) else target + val currentNestingLevel = ctx.nestingLevel atPhaseNoEarlier(explicitOuterPhase.next) { // outer accessors are entered at explicitOuter + 1, should not be defined before. - newSymbol(owner, name, SyntheticArtifact | flags, info, coord = cls.coord) + newSymbol(owner, name, SyntheticArtifact | flags, info, coord = cls.coord, nestingLevel = currentNestingLevel) } } diff --git a/tests/neg/i16343.scala b/tests/neg/i16343.scala new file mode 100644 index 000000000000..d09ffcbe32c7 --- /dev/null +++ b/tests/neg/i16343.scala @@ -0,0 +1,2 @@ +class Issue16343: + class MyWorker extends javax.swing.SwingWorker[Unit, Unit] // error