Skip to content

Commit

Permalink
Fix Scala 2 unpickler: do not load case accessor vals
Browse files Browse the repository at this point in the history
The class file contains both a case accessor `private val` and a case
accessor `def`. We only need to load the `def` accessor.
  • Loading branch information
nicolasstucki committed Nov 10, 2023
1 parent 032f6cd commit 438bd01
Show file tree
Hide file tree
Showing 5 changed files with 6 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ jobs:
./project/scripts/sbt ";sjsSandbox/run ;sjsSandbox/test ;sjsJUnitTests/test ;set sjsJUnitTests/scalaJSLinkerConfig ~= switchToESModules ;sjsJUnitTests/test ;sjsCompilerTests/test"
- name: Test with Scala 2 library TASTy
run: ./project/scripts/sbt ";set ThisBuild/Build.useScala2LibraryTasty := true ;scala3-bootstrapped/testCompilation i5" # only test a subset of test to avoid doubling the CI execution time
run: ./project/scripts/sbt ";set ThisBuild/Build.useScala2LibraryTasty := true ;scala3-bootstrapped/testCompilation i5; scala3-bootstrapped/testCompilation tests/run/typelevel-peano.scala" # only test a subset of test to avoid doubling the CI execution time

test_windows_fast:
runs-on: [self-hosted, Windows]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,8 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
// 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
// We discard the private val representing a case accessor. We only load the case accessor def.
|| flags.isAllOf(CaseAccessor| PrivateLocal, butNot = Method)
then
// skip this member
return NoSymbol
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/inlines/InlineReducer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ class InlineReducer(inliner: Inliner)(using Context):
val paramCls = paramType.classSymbol
if (paramCls.is(Case) && unapp.symbol.is(Synthetic) && scrut <:< paramType) {
val caseAccessors =
if (paramCls.is(Scala2x)) paramCls.caseAccessors.filter(_.is(Method))
if paramCls.is(Scala2x) then paramCls.caseAccessors
else paramCls.asClass.paramAccessors
val selectors =
for (accessor <- caseAccessors)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ object PatternMatcher {
/** Plan for matching the result of an unapply against argument patterns `args` */
def unapplyPlan(unapp: Tree, args: List[Tree]): Plan = {
def caseClass = unapp.symbol.owner.linkedClass
lazy val caseAccessors = caseClass.caseAccessors.filter(_.is(Method))
lazy val caseAccessors = caseClass.caseAccessors

def isSyntheticScala2Unapply(sym: Symbol) =
sym.isAllOf(SyntheticCase) && sym.owner.is(Scala2x)
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Synthesizer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
New(defn.RuntimeTupleMirrorTypeRef, Literal(Constant(arity)) :: Nil)

def makeProductMirror(pre: Type, cls: Symbol, tps: Option[List[Type]]): TreeWithErrors =
val accessors = cls.caseAccessors.filterNot(_.isAllOf(PrivateLocal))
val accessors = cls.caseAccessors
val elemLabels = accessors.map(acc => ConstantType(Constant(acc.name.toString)))
val typeElems = tps.getOrElse(accessors.map(mirroredType.resultType.memberInfo(_).widenExpr))
val nestedPairs = TypeOps.nestedPairs(typeElems)
Expand Down

0 comments on commit 438bd01

Please sign in to comment.