From 8803595e1161036989368222849a4832507e8b0a Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 7 May 2018 10:45:57 +0200 Subject: [PATCH 1/4] Fix #4395: Handle ## when it is an Ident --- .../dotc/transform/InterceptedMethods.scala | 40 ++++++++----------- tests/pos/i4395.scala | 4 ++ 2 files changed, 21 insertions(+), 23 deletions(-) create mode 100644 tests/pos/i4395.scala diff --git a/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala b/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala index c01139e4dda7..b86917f695c1 100644 --- a/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala +++ b/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala @@ -1,31 +1,15 @@ package dotty.tools.dotc package transform -import MegaPhase._ -import core.Denotations._ -import core.SymDenotations._ -import core.Contexts._ -import core.Types._ -import ast.Trees._ -import ast.tpd.{Apply, Tree, cpy} -import dotty.tools.dotc.ast.tpd -import scala.collection.mutable -import dotty.tools.dotc._ -import core._ -import Contexts._ -import Symbols._ -import Decorators._ -import NameOps._ import dotty.tools.dotc.ast.Trees._ -import dotty.tools.dotc.ast.{untpd, tpd} +import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.core.Constants.Constant -import dotty.tools.dotc.core.Types.MethodType -import dotty.tools.dotc.core.Names.{ Name, TermName } -import scala.collection.mutable.ListBuffer -import dotty.tools.dotc.core.Denotations.SingleDenotation -import dotty.tools.dotc.core.SymDenotations.SymDenotation -import StdNames._ -import Phases.Phase +import dotty.tools.dotc.core.Contexts._ +import dotty.tools.dotc.core.Names.TermName +import dotty.tools.dotc.core.StdNames._ +import dotty.tools.dotc.core.Symbols._ +import dotty.tools.dotc.core.Types._ +import dotty.tools.dotc.transform.MegaPhase.MiniPhase object InterceptedMethods { val name = "intercepted" @@ -54,6 +38,16 @@ class InterceptedMethods extends MiniPhase { else tree } + override def transformIdent(tree: tpd.Ident)(implicit ctx: Context): Tree = { + if (tree.symbol.isTerm && (defn.Any_## eq tree.symbol.asTerm)) { + val cls = ctx.owner.ownersIterator.find(_.isClass).get.asClass + val rewrite = poundPoundValue(This(cls)) + ctx.log(s"$phaseName rewrote $tree to $rewrite") + rewrite + } + else tree + } + // TODO: add missing cases from scalac private def poundPoundValue(tree: Tree)(implicit ctx: Context) = { val s = tree.tpe.widen.typeSymbol diff --git a/tests/pos/i4395.scala b/tests/pos/i4395.scala new file mode 100644 index 000000000000..d53f96ce2e32 --- /dev/null +++ b/tests/pos/i4395.scala @@ -0,0 +1,4 @@ +object Test { + val res0 = ## + val res1 = this.## +} From d32bd8df3fd4cc18f5f1bbf0c8288433cf67783c Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 7 May 2018 10:52:33 +0200 Subject: [PATCH 2/4] Add tests for intercepted method handled as Ident --- tests/pos/i4395b.scala | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 tests/pos/i4395b.scala diff --git a/tests/pos/i4395b.scala b/tests/pos/i4395b.scala new file mode 100644 index 000000000000..a1629a95c85c --- /dev/null +++ b/tests/pos/i4395b.scala @@ -0,0 +1,5 @@ +object Test { + val res0 = ==(null) + val res1 = !=(null) + val res4 = getClass +} From d95f8d48e354d5f447ee2f421a01f6f9abb6b5f2 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 7 May 2018 11:24:30 +0200 Subject: [PATCH 3/4] Use tpd.desugarIdentPrefix --- .../src/dotty/tools/dotc/transform/InterceptedMethods.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala b/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala index b86917f695c1..7f23a1bc6292 100644 --- a/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala +++ b/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala @@ -40,8 +40,7 @@ class InterceptedMethods extends MiniPhase { override def transformIdent(tree: tpd.Ident)(implicit ctx: Context): Tree = { if (tree.symbol.isTerm && (defn.Any_## eq tree.symbol.asTerm)) { - val cls = ctx.owner.ownersIterator.find(_.isClass).get.asClass - val rewrite = poundPoundValue(This(cls)) + val rewrite = poundPoundValue(tpd.desugarIdentPrefix(tree)) ctx.log(s"$phaseName rewrote $tree to $rewrite") rewrite } From 02cbf1f2b997cc249b66d603cb1eade35a36ef27 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 7 May 2018 11:39:34 +0200 Subject: [PATCH 4/4] Factor out more code --- .../dotc/transform/InterceptedMethods.scala | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala b/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala index 7f23a1bc6292..e9843c0a5f34 100644 --- a/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala +++ b/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala @@ -29,18 +29,19 @@ class InterceptedMethods extends MiniPhase { override def phaseName: String = InterceptedMethods.name // this should be removed if we have guarantee that ## will get Apply node - override def transformSelect(tree: tpd.Select)(implicit ctx: Context): Tree = { - if (tree.symbol.isTerm && (defn.Any_## eq tree.symbol.asTerm)) { - val rewrite = poundPoundValue(tree.qualifier) - ctx.log(s"$phaseName rewrote $tree to $rewrite") - rewrite - } - else tree - } + override def transformSelect(tree: tpd.Select)(implicit ctx: Context): Tree = + transformRefTree(tree) + + override def transformIdent(tree: tpd.Ident)(implicit ctx: Context): Tree = + transformRefTree(tree) - override def transformIdent(tree: tpd.Ident)(implicit ctx: Context): Tree = { - if (tree.symbol.isTerm && (defn.Any_## eq tree.symbol.asTerm)) { - val rewrite = poundPoundValue(tpd.desugarIdentPrefix(tree)) + private def transformRefTree(tree: RefTree)(implicit ctx: Context): Tree = { + if (tree.symbol.isTerm && (defn.Any_## eq tree.symbol)) { + val qual = tree match { + case id: Ident => tpd.desugarIdentPrefix(id) + case sel: Select => sel.qualifier + } + val rewrite = poundPoundValue(qual) ctx.log(s"$phaseName rewrote $tree to $rewrite") rewrite }