diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 2e6b12784f6..f83eb433baa 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -263,7 +263,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } /** Symbol is a specialized accessor for the `target` field. */ - case class SpecializedAccessor(target: Symbol) extends SpecializedInfo { } + case class SpecializedAccessor(target: Symbol) extends SpecializedInfo /** Symbol is a specialized method whose body should be the target's method body. */ case class Implementation(target: Symbol) extends SpecializedInfo @@ -602,7 +602,6 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { * was both already used for a map and mucho long. So "sClass" is the * specialized subclass of "clazz" throughout this file. */ - val clazzName = specializedName(clazz, env0).toTypeName // scala/bug#5545: Eliminate classes with the same name loaded from the bytecode already present - all we need to do is // to force .info on them, as their lazy type will be evaluated and the symbols will be eliminated. Unfortunately @@ -844,7 +843,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { info(origGetter) = Forward(specGetter) enterMember(specGetter) enterMember(origGetter) - debuglog("specialize accessor in %s: %s -> %s".format(sClass.name.decode, origGetter.name.decode, specGetter.name.decode)) + debuglog(s"specialize accessor in ${sClass.name.decode}: ${origGetter.name.decode} -> ${specGetter.name.decode}") clazz.caseFieldAccessors.find(_.name.startsWith(m.name)) foreach { cfa => val cfaGetter = overrideIn(sClass, cfa) @@ -1995,14 +1994,12 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { ) ) // param accessors for private members (the others are inherited from the generic class) - if (m.isPrimaryConstructor) { - for (param <- vparams ; if sClass.info.nonPrivateMember(param.name) == NoSymbol) { + if (m.isPrimaryConstructor) + for (param <- vparams if sClass.info.nonPrivateMember(param.name) == NoSymbol) { val acc = param.cloneSymbol(sClass, param.flags | PARAMACCESSOR | PrivateLocal) sClass.info.decls.enter(acc) mbrs += ValDef(acc, EmptyTree).setType(NoType).setPos(m.pos) } - } - // ctor mbrs += DefDef(m, Modifiers(m.flags), mmap(List(vparams))(ValDef.apply), EmptyTree) } else { diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 5ec518db13d..875a9ea010e 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -2136,8 +2136,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => * argument in the first parameter list of the primary constructor. * The empty list for all other classes. * - * This list will be sorted to correspond to the declaration order - * in the constructor parameter + * This list will be sorted to correspond to the declaration order + * in the constructor parameter */ final def caseFieldAccessors: List[Symbol] = { // We can't rely on the ordering of the case field accessors within decls -- @@ -2148,22 +2148,26 @@ trait Symbols extends api.Symbols { self: SymbolTable => // // The slightly more principled approach of using the paramss of the // primary constructor leads to cycles in, for example, pos/t5084.scala. - val primaryNames = constrParamAccessors map (_.name.dropLocal) - def nameStartsWithOrigDollar(name: Name, prefix: Name) = - name.startsWith(prefix) && name.length > prefix.length + 1 && name.charAt(prefix.length) == '$' + val primaryNames = constrParamAccessors.map { p => + if (p.hasFlag(EXPANDEDNAME)) p.unexpandedName.dropLocal + else p.name.dropLocal + } - def rec(remaningAccessors: List[Symbol], foundAccessors: List[(Symbol, Int)], remainingNames: List[(Name, Int)]): List[Symbol] = { - remaningAccessors match { + def loop(remainingAccessors: List[Symbol], foundAccessors: List[(Symbol, Int)], remainingNames: List[(Name, Int)]): List[Symbol] = + remainingAccessors match { case Nil => foundAccessors.sortBy(_._2).map(_._1) - case acc :: tail => { - val i = remainingNames.collectFirst { case (name, i) if acc.name == name || nameStartsWithOrigDollar(acc.name, name) => i} - rec(tail, (acc, i.get) :: foundAccessors, remainingNames.filterNot { case (_, ii) => Some(ii) == i} ) - } + case acc :: remainingAccessors => + def nameStartsWithOrigDollar(name: Name, prefix: Name) = + name.startsWith(prefix) && name.length > prefix.length + 1 && name.charAt(prefix.length) == '$' + remainingNames.collectFirst { + case (name, i) if acc.name == name || nameStartsWithOrigDollar(acc.name, name) => i + } match { + case Some(i) => loop(remainingAccessors, (acc, i) :: foundAccessors, remainingNames.filter(_._2 != i)) + case x => throw new MatchError(x) + } } - } - - rec(caseFieldAccessorsUnsorted.sortBy(s => -s.name.length), Nil, primaryNames.zipWithIndex.sortBy{ case (n, _) => -n.length}) + loop(caseFieldAccessorsUnsorted.sortBy(-_.name.length), foundAccessors = Nil, primaryNames.zipWithIndex.sortBy(-_._1.length)) } private final def caseFieldAccessorsUnsorted: List[Symbol] = info.decls.toList.filter(_.isCaseAccessorMethod) diff --git a/test/files/pos/t12988.scala b/test/files/pos/t12988.scala new file mode 100644 index 00000000000..45234ed3a19 --- /dev/null +++ b/test/files/pos/t12988.scala @@ -0,0 +1,12 @@ +object example { + final case class Toto[@specialized(Int) A] (private val actualToString: String, a: A) { + @inline def description: String = actualToString + } + def toto[A](a: A): Toto[A] = Toto("", a) +} + +object Test extends App { + import example._ + + println(s"Hello World! ${toto(1)}") +} diff --git a/test/files/run/t12222.check b/test/files/run/t12222.check deleted file mode 100644 index 573541ac970..00000000000 --- a/test/files/run/t12222.check +++ /dev/null @@ -1 +0,0 @@ -0 diff --git a/test/files/run/t12222/Test_2.scala b/test/files/run/t12222/Test_2.scala index a5c975cd349..bf908d84c5c 100644 --- a/test/files/run/t12222/Test_2.scala +++ b/test/files/run/t12222/Test_2.scala @@ -2,6 +2,6 @@ object Test { def main(args: Array[String]): Unit = { val vertices = Array[Float]() val attribute = new Float32Buffer(vertices) - println(attribute.count) + assert(attribute.count == 0) } -} \ No newline at end of file +} diff --git a/test/files/run/t6387.scala b/test/files/run/t6387.scala new file mode 100644 index 00000000000..be792ca6899 --- /dev/null +++ b/test/files/run/t6387.scala @@ -0,0 +1,14 @@ +trait A { + def foo: Long +} + +object Test { + def a(): A = new A { + var foo: Long = 1024L + + val test = () => { + foo = 28 + } + } + def main(args: Array[String]) = assert(a().foo == 1024L) +} diff --git a/test/files/run/t6608.check b/test/files/run/t6608.check deleted file mode 100644 index 15628b322ea..00000000000 --- a/test/files/run/t6608.check +++ /dev/null @@ -1 +0,0 @@ -(C$$yyy,true) diff --git a/test/files/run/t6608.scala b/test/files/run/t6608.scala index 2ba979649bc..f1d502be7f0 100644 --- a/test/files/run/t6608.scala +++ b/test/files/run/t6608.scala @@ -11,6 +11,7 @@ object Test extends App { .toList .filter(_.name.toString.endsWith("yyy")) .map(x => (x.name, x.isPrivate)) - println(access.head) + val Expected = TermName("C$$yyy") + assert(access.head == (Expected, true)) }