Skip to content

Commit

Permalink
Reinterpret Scala 2 case accessors xyz$access$idx (#18907)
Browse files Browse the repository at this point in the history
Fixes  #18884
Related to #18874
  • Loading branch information
nicolasstucki committed Nov 17, 2023
2 parents 3b974c5 + b035f76 commit 50498d8
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,14 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
flags &~= Method | Accessor
if !flags.is(StableRealizable) then flags |= Mutable

// Skip case accessor `<xyz>$access$<idx>` and keep track of their name to make `<xyz>` the case accessor
if flags.is(CaseAccessor) && name.toString().contains("$access$") then
val accessorName = name.toString().split('$').head.toTermName // <xyz>
symScope(owner) // we assume that the `<xyz>` is listed before the accessor and hence is already entered in the scope
.find(decl => decl.isAllOf(ParamAccessor) && decl.name == accessorName)
.setFlag(CaseAccessor)
return NoSymbol // skip this member

name = name.adjustIfModuleClass(flags)
if (flags.is(Method))
name =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1058,7 +1058,7 @@ class DottyBytecodeTests extends DottyBytecodeTest {
TypeOp(CHECKCAST, "scala/collection/immutable/$colon$colon"),
VarOp(ASTORE, 3),
VarOp(ALOAD, 3),
Invoke(INVOKEVIRTUAL, "scala/collection/immutable/$colon$colon", "next$access$1", "()Lscala/collection/immutable/List;", false),
Invoke(INVOKEVIRTUAL, "scala/collection/immutable/$colon$colon", "next", "()Lscala/collection/immutable/List;", false),
VarOp(ASTORE, 4),
VarOp(ALOAD, 3),
Invoke(INVOKEVIRTUAL, "scala/collection/immutable/$colon$colon", "head", "()Ljava/lang/Object;", false),
Expand Down Expand Up @@ -1112,7 +1112,7 @@ class DottyBytecodeTests extends DottyBytecodeTest {
Invoke(INVOKESTATIC, "scala/runtime/BoxesRunTime", "unboxToInt", "(Ljava/lang/Object;)I", false),
VarOp(ISTORE, 4),
VarOp(ALOAD, 3),
Invoke(INVOKEVIRTUAL, "scala/collection/immutable/$colon$colon", "next$access$1", "()Lscala/collection/immutable/List;", false),
Invoke(INVOKEVIRTUAL, "scala/collection/immutable/$colon$colon", "next", "()Lscala/collection/immutable/List;", false),
VarOp(ASTORE, 5),
Op(ICONST_1),
VarOp(ILOAD, 4),
Expand Down
39 changes: 30 additions & 9 deletions compiler/test/dotty/tools/vulpix/ParallelTesting.scala
Original file line number Diff line number Diff line change
Expand Up @@ -610,17 +610,38 @@ trait ParallelTesting extends RunnerOrchestration { self =>
.run()
.mkString(JFile.pathSeparator)

val stdlibClasspath = artifactClasspath("org.scala-lang", "scala3-library_3")
val scalacClasspath = artifactClasspath("org.scala-lang", "scala3-compiler_3")

val pageWidth = TestConfiguration.pageWidth - 20
val flags1 = flags.copy(defaultClassPath = stdlibClasspath)
.withClasspath(targetDir.getPath)
.and("-d", targetDir.getPath)
.and("-pagewidth", pageWidth.toString)

val scalacCommand = Array("java", "-cp", scalacClasspath, "dotty.tools.dotc.Main")
val command = scalacCommand ++ flags1.all ++ files.map(_.getAbsolutePath)
val fileArgs = files.map(_.getAbsolutePath)

def scala2Command(): Array[String] = {
assert(!flags.options.contains("-scalajs"),
"Compilation tests with Scala.js on Scala 2 are not supported.\nThis test can be skipped using the `// scalajs: --skip` tag")
val stdlibClasspath = artifactClasspath("org.scala-lang", "scala-library")
val scalacClasspath = artifactClasspath("org.scala-lang", "scala-compiler")
val flagsArgs = flags
.copy(options = Array.empty, defaultClassPath = stdlibClasspath)
.withClasspath(targetDir.getPath)
.and("-d", targetDir.getPath)
.all
val scalacCommand = Array("java", "-cp", scalacClasspath, "scala.tools.nsc.Main")
scalacCommand ++ flagsArgs ++ fileArgs
}

def scala3Command(): Array[String] = {
val stdlibClasspath = artifactClasspath("org.scala-lang", "scala3-library_3")
val scalacClasspath = artifactClasspath("org.scala-lang", "scala3-compiler_3")
val flagsArgs = flags
.copy(defaultClassPath = stdlibClasspath)
.withClasspath(targetDir.getPath)
.and("-d", targetDir.getPath)
.and("-pagewidth", pageWidth.toString)
.all
val scalacCommand = Array("java", "-cp", scalacClasspath, "dotty.tools.dotc.Main")
scalacCommand ++ flagsArgs ++ fileArgs
}

val command = if compiler.startsWith("2") then scala2Command() else scala3Command()
val process = Runtime.getRuntime.exec(command)

val reporter = mkReporter
Expand Down
2 changes: 2 additions & 0 deletions tests/neg/i18884.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def test(xs: ::[Int]): List[Int] =
xs.next$access$1 // error
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)
10 changes: 10 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,10 @@
// scalajs: --skip

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)")
6 changes: 3 additions & 3 deletions tests/run/typeclass-derivation3.check
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ Cons(hd = Cons(hd = 11, tl = Cons(hd = 22, tl = Cons(hd = 33, tl = Nil))), tl =
Cons(hd = Left(x = 1), tl = Cons(hd = Right(x = Pair(x = 2, y = 3)), tl = Nil))
Cons(hd = Left(x = 1), tl = Cons(hd = Right(x = Pair(x = 2, y = 3)), tl = Nil))
true
::(head = 1, next$access$1 = ::(head = 2, next$access$1 = ::(head = 3, next$access$1 = Nil())))
::(head = ::(head = 1, next$access$1 = Nil()), next$access$1 = ::(head = ::(head = 2, next$access$1 = ::(head = 3, next$access$1 = Nil())), next$access$1 = Nil()))
::(head = Nil(), next$access$1 = ::(head = ::(head = 1, next$access$1 = Nil()), next$access$1 = ::(head = ::(head = 2, next$access$1 = ::(head = 3, next$access$1 = Nil())), next$access$1 = Nil())))
::(head = 1, next = ::(head = 2, next = ::(head = 3, next = Nil())))
::(head = ::(head = 1, next = Nil()), next = ::(head = ::(head = 2, next = ::(head = 3, next = Nil())), next = Nil()))
::(head = Nil(), next = ::(head = ::(head = 1, next = Nil()), next = ::(head = ::(head = 2, next = ::(head = 3, next = Nil())), next = Nil())))

0 comments on commit 50498d8

Please sign in to comment.