Skip to content

Commit

Permalink
Generalize Scala 2 xyz$accessor$idx fix
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolasstucki committed Nov 14, 2023
1 parent bfe4f05 commit c71e8a1
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -454,13 +454,18 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
// skip this member
return NoSymbol

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

name = name.adjustIfModuleClass(flags)
if (flags.is(Method))
Expand Down
4 changes: 4 additions & 0 deletions tests/run/i18884.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Foo1(1)
Foo2(2, 3)
Foo3(4, 5)
Foo4(6, 7)
8 changes: 8 additions & 0 deletions tests/run/i18884/A_1_c2.13.12.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package lib

case class Foo1(private[lib] var x: Int) {}
case class Foo2(private[lib] var x: Int, private[lib] var y: Int)
case class Foo3(private[lib] var x: Int, var y: Int)
case class Foo4(var x: Int, private[lib] var y: Int) {
val z: Int = x
}
14 changes: 14 additions & 0 deletions tests/run/i18884/B_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import lib.*

@main def Test: Unit =
test(new Foo1(1))
test(new Foo2(2, 3))
test(new Foo3(4, 5))
test(new Foo4(6, 7))

def test(any: Any): Unit =
any match
case Foo1(x) => println(s"Foo1($x)")
case Foo2(x, y) => println(s"Foo2($x, $y)")
case Foo3(x, y) => println(s"Foo3($x, $y)")
case Foo4(x, y) => println(s"Foo4($x, $y)")

0 comments on commit c71e8a1

Please sign in to comment.