From e9fecd393a3c355a68207da4bb1fa9fcf47eafc9 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 18 Feb 2017 12:54:36 +0100 Subject: Fix #1990: Handle case where inlining changes class of outer The new situation in the test was that outer of the inlined method was `A` but it's as seen from type is a subtype `B`. We need two fixes: - Ignore outerSelects in TreeChecker. These are treated as having fixed symbols. - Adapt the outer-path logic to deal with code that's moved to another context. --- tests/pos/i1990.scala | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/pos/i1990.scala (limited to 'tests/pos') diff --git a/tests/pos/i1990.scala b/tests/pos/i1990.scala new file mode 100644 index 000000000..77cea0af7 --- /dev/null +++ b/tests/pos/i1990.scala @@ -0,0 +1,12 @@ +class A { + class Foo { + inline def inlineMeth: Unit = { + new Bar + } + } + class Bar +} + +class B extends A { + (new Foo).inlineMeth +} -- cgit v1.2.3 From c54e942ef6275fc0c61c051539a1b37f4e12123c Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 19 Feb 2017 09:29:28 +0100 Subject: Fix sorting of accessed this-proxies They are sorted according to the nesting depth of the classes they represent. This is no necessarily the same as the nesting level of the symbols of the proxy classes. i1990a.scala shows an example where the two differ. --- compiler/src/dotty/tools/dotc/typer/Inliner.scala | 7 ++++++- tests/pos/i1990a.scala | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i1990a.scala (limited to 'tests/pos') diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index cfc0003c6..6cf69b97c 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -402,7 +402,12 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) { def outerLevel(selfSym: Symbol): Int = classOf(selfSym).ownersIterator.length // All needed this-proxies, sorted by nesting depth of the classes they represent (innermost first) - val accessedSelfSyms = thisProxy.values.toList.map(_.symbol).sortBy(-outerLevel(_)) + val accessedSelfSyms = + thisProxy.toList.sortBy { + case (cls, proxy) => -outerLevel(cls) + } map { + case (cls, proxy) => proxy.symbol + } // Compute val-definitions for all this-proxies and append them to `bindingsBuf` var lastSelf: Symbol = NoSymbol diff --git a/tests/pos/i1990a.scala b/tests/pos/i1990a.scala new file mode 100644 index 000000000..f6f95ee36 --- /dev/null +++ b/tests/pos/i1990a.scala @@ -0,0 +1,20 @@ +class A { self => + class Foo { + inline def inlineMeth: Unit = { + println(self) + } + } +} + +class C extends A { + class B extends A +} + +object Test { + def main(args: Array[String]): Unit = { + val c = new C + val b = new c.B + + (new b.Foo).inlineMeth + } +} -- cgit v1.2.3