From 0d659388a720b72a9e478a740f6040589ba8c964 Mon Sep 17 00:00:00 2001 From: odersky Date: Wed, 13 Jul 2022 18:55:46 +0200 Subject: [PATCH 1/2] Fix computation of class nesting level in inliner Fixes #15666 --- compiler/src/dotty/tools/dotc/typer/Inliner.scala | 7 +++++-- tests/pos/i15666.scala | 11 +++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 tests/pos/i15666.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index 52a51305e995..48de25e05f07 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -613,12 +613,15 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) { assert(argss.isEmpty) true + /** The number of enclosing classes of this class, plus one */ + private def nestingLevel(cls: Symbol) = cls.ownersIterator.count(_.isClass) + // Compute val-definitions for all this-proxies and append them to `bindingsBuf` private def computeThisBindings() = { // All needed this-proxies, paired-with and sorted-by nesting depth of // the classes they represent (innermost first) val sortedProxies = thisProxy.toList - .map((cls, proxy) => (cls.ownersIterator.length, proxy.symbol)) + .map((cls, proxy) => (nestingLevel(cls), proxy.symbol)) .sortBy(-_._1) var lastSelf: Symbol = NoSymbol @@ -640,7 +643,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) { val pre = inlineCallPrefix match case Super(qual, _) => qual case pre => pre - val preLevel = inlinedMethod.owner.ownersIterator.length + val preLevel = nestingLevel(inlinedMethod.owner) if preLevel > level then pre.outerSelect(preLevel - level, selfSym.info) else pre diff --git a/tests/pos/i15666.scala b/tests/pos/i15666.scala new file mode 100644 index 000000000000..ad7314201565 --- /dev/null +++ b/tests/pos/i15666.scala @@ -0,0 +1,11 @@ +trait GetInt { + def value: Int // if we add inline here, the program compiles +} + +class Newtype { + def f: Int = ??? + + val g = new GetInt { + inline def value: Int = f // has to be inline to crash + } +} \ No newline at end of file From f013bbf9c782a5d1ea8f3934492b232af73059fd Mon Sep 17 00:00:00 2001 From: odersky Date: Wed, 13 Jul 2022 19:06:16 +0200 Subject: [PATCH 2/2] Rename to classNestingLevel --- compiler/src/dotty/tools/dotc/typer/Inliner.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index 48de25e05f07..bc5b2d040cbb 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -614,14 +614,14 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) { true /** The number of enclosing classes of this class, plus one */ - private def nestingLevel(cls: Symbol) = cls.ownersIterator.count(_.isClass) + private def classNestingLevel(cls: Symbol) = cls.ownersIterator.count(_.isClass) // Compute val-definitions for all this-proxies and append them to `bindingsBuf` private def computeThisBindings() = { // All needed this-proxies, paired-with and sorted-by nesting depth of // the classes they represent (innermost first) val sortedProxies = thisProxy.toList - .map((cls, proxy) => (nestingLevel(cls), proxy.symbol)) + .map((cls, proxy) => (classNestingLevel(cls), proxy.symbol)) .sortBy(-_._1) var lastSelf: Symbol = NoSymbol @@ -643,7 +643,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) { val pre = inlineCallPrefix match case Super(qual, _) => qual case pre => pre - val preLevel = nestingLevel(inlinedMethod.owner) + val preLevel = classNestingLevel(inlinedMethod.owner) if preLevel > level then pre.outerSelect(preLevel - level, selfSym.info) else pre