Skip to content

Commit a7691fe

Browse files
committed
Correctly unpickle Scala 2 private case classes in traits
Fixes #16443 I don't know how to make a test that reproduces the exact problem. In the test of this commit `TypeHints_1.scala` should be compiled with Scala 2.13, but I am not sure how to implement that.
1 parent c3097af commit a7691fe

File tree

4 files changed

+26
-5
lines changed

4 files changed

+26
-5
lines changed

compiler/src/dotty/tools/dotc/core/NamerOps.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ object NamerOps:
6767
completer.withSourceModule(findModuleBuddy(name.sourceModuleName, scope))
6868

6969
/** Find moduleClass/sourceModule in effective scope */
70-
def findModuleBuddy(name: Name, scope: Scope)(using Context) = {
71-
val it = scope.lookupAll(name).filter(_.is(Module))
72-
if (it.hasNext) it.next()
70+
def findModuleBuddy(name: Name, scope: Scope, alternate: Name = EmptyTermName)(using Context): Symbol =
71+
var it = scope.lookupAll(name).filter(_.is(Module))
72+
if !alternate.isEmpty then it ++= scope.lookupAll(alternate).filter(_.is(Module))
73+
if it.hasNext then it.next()
7374
else NoSymbol.assertingErrorsReported(em"no companion $name in $scope")
74-
}
7575

7676
/** If a class has one of these flags, it does not get a constructor companion */
7777
private val NoConstructorProxyNeededFlags = Abstract | Trait | Case | Synthetic | Module | Invisible

compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,11 @@ object Scala2Unpickler {
8989
val sourceModule = denot.sourceModule.orElse {
9090
// For non-toplevel modules, `sourceModule` won't be set when completing
9191
// the module class, we need to go find it ourselves.
92-
NamerOps.findModuleBuddy(cls.name.sourceModuleName, denot.owner.info.decls)
92+
val modName = cls.name.sourceModuleName
93+
val alternate =
94+
if cls.privateWithin.exists && cls.owner.is(Trait) then modName.expandedName(cls.owner)
95+
else EmptyTermName
96+
NamerOps.findModuleBuddy(modName, denot.owner.info.decls, alternate)
9397
}
9498
denot.owner.thisType.select(sourceModule)
9599
else selfInfo

tests/pos/i16443/Test_2.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@main def Test =
2+
println(NoTypeHints)

tests/pos/i16443/TypeHints_1.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// This should be run with Scala 2.13
2+
trait TypeHints {
3+
val hints: List[Class[_]]
4+
def components: List[TypeHints] = List(this)
5+
6+
def + (hints: TypeHints): TypeHints = CompositeTypeHints(components ::: hints.components)
7+
8+
private case class CompositeTypeHints(override val components: List[TypeHints]) extends TypeHints {
9+
override val hints: List[Class[_]] = components.flatMap(_.hints)
10+
}
11+
}
12+
13+
case object NoTypeHints extends TypeHints {
14+
override val hints = Nil
15+
}

0 commit comments

Comments
 (0)