Skip to content

Commit c71e8a1

Browse files
committed
Generalize Scala 2 xyz$accessor$idx fix
1 parent bfe4f05 commit c71e8a1

File tree

4 files changed

+38
-7
lines changed

4 files changed

+38
-7
lines changed

Diff for: compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala

+12-7
Original file line numberDiff line numberDiff line change
@@ -454,13 +454,18 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
454454
// skip this member
455455
return NoSymbol
456456

457-
// Remove case accessor `next$access$1` and make `next` the case accessor
458-
// TODO generalize to all Scala 2 accessors with this form
459-
if owner == defn.ConsClass then
460-
if name == nme.next then
461-
flags = flags | CaseAccessor
462-
else if name == "next$access$1".toTermName then
463-
return NoSymbol
457+
// Skip case accessor `<xyz>$access$<idx>` and make `<xyz>` the case accessor
458+
if flags.is(CaseAccessor) && name.toString().contains("$access$") then
459+
// The only way to know if the accessor needs the additional `CaseAccessor` flag is
460+
// when we see the `<xyz>$access$<idx>` accessor. When we load `<xyz>` we have not
461+
// loaded or have skipped `<xyz>$access$<idx>`. Furthermore, its flags are
462+
// undistinguishable from non-case parameter accessors (example
463+
// `case class Foo(private[p] var x: T)(private[p] var y: T)`).
464+
val accessorIndex = name.toString().split('$').last.toInt
465+
val accessors = owner.asClass.info.decls
466+
.filter(decl => decl.isAllOf(Accessor | ParamAccessor) && !decl.name.endsWith("_="))
467+
accessors(accessorIndex).setFlag(CaseAccessor)
468+
return NoSymbol // skip `<xyz>$access$<idx>`
464469

465470
name = name.adjustIfModuleClass(flags)
466471
if (flags.is(Method))

Diff for: tests/run/i18884.check

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Foo1(1)
2+
Foo2(2, 3)
3+
Foo3(4, 5)
4+
Foo4(6, 7)

Diff for: tests/run/i18884/A_1_c2.13.12.scala

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package lib
2+
3+
case class Foo1(private[lib] var x: Int) {}
4+
case class Foo2(private[lib] var x: Int, private[lib] var y: Int)
5+
case class Foo3(private[lib] var x: Int, var y: Int)
6+
case class Foo4(var x: Int, private[lib] var y: Int) {
7+
val z: Int = x
8+
}

Diff for: tests/run/i18884/B_2.scala

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import lib.*
2+
3+
@main def Test: Unit =
4+
test(new Foo1(1))
5+
test(new Foo2(2, 3))
6+
test(new Foo3(4, 5))
7+
test(new Foo4(6, 7))
8+
9+
def test(any: Any): Unit =
10+
any match
11+
case Foo1(x) => println(s"Foo1($x)")
12+
case Foo2(x, y) => println(s"Foo2($x, $y)")
13+
case Foo3(x, y) => println(s"Foo3($x, $y)")
14+
case Foo4(x, y) => println(s"Foo4($x, $y)")

0 commit comments

Comments
 (0)