From 71e7924cb2a52e317c7e009c6dcb69cdaacbb83a Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 23 Dec 2020 19:47:46 +0100 Subject: [PATCH] Fix #10905: Fix explicitSelf phase We need to rewire also some references that are simple identifiers. --- .../tools/dotc/transform/ExplicitSelf.scala | 21 ++++++++++++------- tests/run/i10905.scala | 6 ++++++ 2 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 tests/run/i10905.scala diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitSelf.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitSelf.scala index 0d28d71ba22a..3a2bda437d80 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExplicitSelf.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExplicitSelf.scala @@ -2,10 +2,7 @@ package dotty.tools.dotc package transform import core._ -import Contexts._ -import Types._ -import MegaPhase._ -import ast.Trees._ +import Contexts._, Types._, MegaPhase._, ast.Trees._, Symbols._, Decorators._, Flags._ /** Transform references of the form * @@ -26,18 +23,28 @@ class ExplicitSelf extends MiniPhase { override def phaseName: String = "explicitSelf" + private def needsCast(tree: RefTree, cls: ClassSymbol)(using Context) = + !cls.is(Package) && cls.givenSelfType.exists && !cls.derivesFrom(tree.symbol.owner) + + private def castQualifier(tree: RefTree, cls: ClassSymbol, thiz: Tree)(using Context) = + cpy.Select(tree)(thiz.cast(AndType(cls.classInfo.selfType, thiz.tpe)), tree.name) + override def transformIdent(tree: Ident)(using Context): Tree = tree.tpe match { case tp: ThisType => report.debuglog(s"owner = ${ctx.owner}, context = ${ctx}") This(tp.cls).withSpan(tree.span) - case _ => tree + case TermRef(thisTp: ThisType, _) => + val cls = thisTp.cls + if needsCast(tree, cls) then castQualifier(tree, cls, This(cls)) + else tree + case _ => + tree } override def transformSelect(tree: Select)(using Context): Tree = tree match { case Select(thiz: This, name) if name.isTermName => val cls = thiz.symbol.asClass - if (cls.givenSelfType.exists && !cls.derivesFrom(tree.symbol.owner)) - cpy.Select(tree)(thiz.cast(AndType(cls.classInfo.selfType, thiz.tpe)), name) + if needsCast(tree, cls) then castQualifier(tree, cls, thiz) else tree case _ => tree } diff --git a/tests/run/i10905.scala b/tests/run/i10905.scala new file mode 100644 index 000000000000..2637d69cc8a2 --- /dev/null +++ b/tests/run/i10905.scala @@ -0,0 +1,6 @@ +class C(val x: Int) extends TypeHelpers +abstract class TypeHelpers: + self: C => + def f = x +@main def Test = + C(0).f