diff --git a/compiler/src/dotty/tools/dotc/core/NameKinds.scala b/compiler/src/dotty/tools/dotc/core/NameKinds.scala index aa11660710b5..e17e772de993 100644 --- a/compiler/src/dotty/tools/dotc/core/NameKinds.scala +++ b/compiler/src/dotty/tools/dotc/core/NameKinds.scala @@ -367,6 +367,7 @@ object NameKinds { val ModuleClassName: SuffixNameKind = new SuffixNameKind(OBJECTCLASS, "$", optInfoString = "ModuleClass") val ImplMethName: SuffixNameKind = new SuffixNameKind(IMPLMETH, "$") val AdaptedClosureName: SuffixNameKind = new SuffixNameKind(ADAPTEDCLOSURE, "$adapted") { override def definesNewName = true } + val SyntheticSetterName: SuffixNameKind = new SuffixNameKind(SETTER, "_$eq") /** A name together with a signature. Used in Tasty trees. */ object SignedName extends NameKind(SIGNED) { diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala index 6cfdedbe9a27..b9d45385f389 100644 --- a/compiler/src/dotty/tools/dotc/core/NameOps.scala +++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala @@ -1,4 +1,5 @@ -package dotty.tools.dotc +package dotty.tools +package dotc package core import java.security.MessageDigest @@ -9,7 +10,7 @@ import Names._, StdNames._, Contexts._, Symbols._, Flags._, NameKinds._, Types._ import util.Chars.{isOperatorPart, digit2int} import Definitions._ import nme._ -import Decorators.concat +import Decorators._ object NameOps { @@ -69,7 +70,7 @@ object NameOps { def isLocalDummyName: Boolean = name startsWith str.LOCALDUMMY_PREFIX def isReplWrapperName: Boolean = name.toString contains str.REPL_SESSION_LINE def isReplAssignName: Boolean = name.toString contains str.REPL_ASSIGN_SUFFIX - def isSetterName: Boolean = name endsWith str.SETTER_SUFFIX + def isSetterName: Boolean = name.endsWith(str.SETTER_SUFFIX) || name.is(SyntheticSetterName) def isScala2LocalSuffix: Boolean = testSimple(_.endsWith(" ")) def isSelectorName: Boolean = testSimple(n => n.startsWith("_") && n.drop(1).forall(_.isDigit)) def isAnonymousClassName: Boolean = name.startsWith(str.ANON_CLASS) @@ -347,17 +348,21 @@ object NameOps { def setterName: TermName = name.exclude(FieldName) ++ str.SETTER_SUFFIX + def syntheticSetterName = SyntheticSetterName(name.exclude(FieldName)) + def getterName: TermName = - name.exclude(FieldName).mapLast(n => + val name1 = name.exclude(FieldName) + if name1.is(SyntheticSetterName) then name1.exclude(SyntheticSetterName) + else name1.mapLast(n => if (n.endsWith(str.SETTER_SUFFIX)) n.take(n.length - str.SETTER_SUFFIX.length).asSimpleName else n) def fieldName: TermName = if (name.isSetterName) - if (name.is(TraitSetterName)) { - val TraitSetterName(_, original) = name - original.fieldName - } + if name.is(SyntheticSetterName) then + name.exclude(SyntheticSetterName) + .replace { case TraitSetterName(_, original) => original } + .fieldName else getterName.fieldName else FieldName(name.toSimpleName) diff --git a/compiler/src/dotty/tools/dotc/core/NameTags.scala b/compiler/src/dotty/tools/dotc/core/NameTags.scala index c570f300a4bf..63aea8853235 100644 --- a/compiler/src/dotty/tools/dotc/core/NameTags.scala +++ b/compiler/src/dotty/tools/dotc/core/NameTags.scala @@ -29,6 +29,8 @@ object NameTags extends TastyFormat.NameTags { final val PARAMACC = 33 // Used for a private parameter alias + final val SETTER = 34 // A synthesized += suffix. + def nameTagToString(tag: Int): String = tag match { case UTF8 => "UTF8" case QUALIFIED => "QUALIFIED" diff --git a/compiler/src/dotty/tools/dotc/transform/Mixin.scala b/compiler/src/dotty/tools/dotc/transform/Mixin.scala index 7b8e2b986e3a..20f40fd96515 100644 --- a/compiler/src/dotty/tools/dotc/transform/Mixin.scala +++ b/compiler/src/dotty/tools/dotc/transform/Mixin.scala @@ -25,7 +25,7 @@ object Mixin { def traitSetterName(getter: TermSymbol)(using Context): TermName = getter.ensureNotPrivate.name .expandedName(getter.owner, TraitSetterName) - .asTermName.setterName + .asTermName.syntheticSetterName } /** This phase performs the following transformations: diff --git a/tests/run/i10285.scala b/tests/run/i10285.scala new file mode 100644 index 000000000000..5019bae43ca7 --- /dev/null +++ b/tests/run/i10285.scala @@ -0,0 +1,25 @@ +trait Companion { + + trait AbstractFoo { + val a0 = 1 + private val b0 = 2 + def b1 = b0 + val (a, b) = { + val av = 1 + val bv = 2 + (av, bv) + } + } +} + +object Bar extends Companion { + class FooImpl extends AbstractFoo + val foo = new FooImpl() +} + +object Test { + val foo = new Bar.FooImpl + def main(args: Array[String]): Unit = + assert(Bar.foo.a0 + Bar.foo.b1 == 3) + assert(Bar.foo.a + Bar.foo.b == 3) +} \ No newline at end of file