From f40070abeea3bbe9b0511fb8e8b8841ac4d4a412 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Mon, 5 Apr 2021 15:15:24 +0200 Subject: [PATCH] Scala2Unpickler: don't unpickle the same type parameter twice Fixes #11173. Fixes #11984. --- .../dotc/core/unpickleScala2/Scala2Unpickler.scala | 12 ++++++++---- .../sbt-test/scala2-compat/i11173/app/App.scala | 3 +++ sbt-dotty/sbt-test/scala2-compat/i11173/build.sbt | 13 +++++++++++++ .../sbt-test/scala2-compat/i11173/lib/Lib.scala | 14 ++++++++++++++ .../scala2-compat/i11173/project/plugins.sbt | 1 + sbt-dotty/sbt-test/scala2-compat/i11173/test | 1 + 6 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 sbt-dotty/sbt-test/scala2-compat/i11173/app/App.scala create mode 100644 sbt-dotty/sbt-test/scala2-compat/i11173/build.sbt create mode 100644 sbt-dotty/sbt-test/scala2-compat/i11173/lib/Lib.scala create mode 100644 sbt-dotty/sbt-test/scala2-compat/i11173/project/plugins.sbt create mode 100644 sbt-dotty/sbt-test/scala2-compat/i11173/test diff --git a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala index 54a7ad91e434..018d382cdcaf 100644 --- a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala @@ -434,12 +434,16 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas var name = at(nameref, () => readName()(using ctx)) val owner = readSymbolRef() - if (name eq nme.getClass_) && defn.hasProblematicGetClass(owner.name) then + var flags = unpickleScalaFlags(readLongNat(), name.isTypeName) + + if (name eq nme.getClass_) && defn.hasProblematicGetClass(owner.name) + // Scala 2 sometimes pickle the same type parameter symbol multiple times + // (see i11173 for an example), but we should only unpickle it once. + || tag == TYPEsym && flags.is(TypeParam) && symScope(owner).lookup(name.asTypeName).exists + then // skip this member return NoSymbol - var flags = unpickleScalaFlags(readLongNat(), name.isTypeName) - name = name.adjustIfModuleClass(flags) if (flags.is(Method)) name = @@ -1333,4 +1337,4 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas case other => errorBadSignature("expected an TypeDef (" + other + ")") } -} \ No newline at end of file +} diff --git a/sbt-dotty/sbt-test/scala2-compat/i11173/app/App.scala b/sbt-dotty/sbt-test/scala2-compat/i11173/app/App.scala new file mode 100644 index 000000000000..9e369179f2cf --- /dev/null +++ b/sbt-dotty/sbt-test/scala2-compat/i11173/app/App.scala @@ -0,0 +1,3 @@ +import i11173.Bar + +def test(x: Bar[_]): Unit = () diff --git a/sbt-dotty/sbt-test/scala2-compat/i11173/build.sbt b/sbt-dotty/sbt-test/scala2-compat/i11173/build.sbt new file mode 100644 index 000000000000..4cc8010e1d38 --- /dev/null +++ b/sbt-dotty/sbt-test/scala2-compat/i11173/build.sbt @@ -0,0 +1,13 @@ +val scala3Version = sys.props("plugin.scalaVersion") +val scala2Version = "2.13.5" + +lazy val lib = project.in(file("lib")) + .settings( + scalaVersion := scala2Version + ) + +lazy val app = project.in(file("app")) + .dependsOn(lib) + .settings( + scalaVersion := scala3Version + ) diff --git a/sbt-dotty/sbt-test/scala2-compat/i11173/lib/Lib.scala b/sbt-dotty/sbt-test/scala2-compat/i11173/lib/Lib.scala new file mode 100644 index 000000000000..468d4767957c --- /dev/null +++ b/sbt-dotty/sbt-test/scala2-compat/i11173/lib/Lib.scala @@ -0,0 +1,14 @@ + +// Compile this with Scala 2.13 +package i11173 + +trait DU[A, B] +trait H[F[_]] + +trait Foo[E] { + def foo: H[({type L[A] = DU[E, A]})#L] +} + +trait Bar[E] extends Foo[E] { + def bar = foo // important note: return type not specified +} diff --git a/sbt-dotty/sbt-test/scala2-compat/i11173/project/plugins.sbt b/sbt-dotty/sbt-test/scala2-compat/i11173/project/plugins.sbt new file mode 100644 index 000000000000..c17caab2d98c --- /dev/null +++ b/sbt-dotty/sbt-test/scala2-compat/i11173/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % sys.props("plugin.version")) diff --git a/sbt-dotty/sbt-test/scala2-compat/i11173/test b/sbt-dotty/sbt-test/scala2-compat/i11173/test new file mode 100644 index 000000000000..19aca297fdcf --- /dev/null +++ b/sbt-dotty/sbt-test/scala2-compat/i11173/test @@ -0,0 +1 @@ +> app/compile