Skip to content

Commit 65a8870

Browse files
committed
Scala2Unpickler: Support structural member selection
Structural members need to be selected by name, not by symbols. Also deleted a special case in finishSym that was dead code: refinement classes are classes so the `owner.isClass` branch was always taken.
1 parent 356dbb3 commit 65a8870

File tree

6 files changed

+32
-4
lines changed

6 files changed

+32
-4
lines changed

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -491,8 +491,6 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
491491
val owner = sym.owner
492492
if (owner.isClass)
493493
owner.asClass.enter(sym, symScope(owner))
494-
else if (isRefinementClass(owner))
495-
symScope(owner).openForMutations.enter(sym)
496494
}
497495
sym
498496
}
@@ -727,6 +725,11 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
727725
* (if restpe is not a ClassInfoType, a MethodType or a NullaryMethodType, which leaves TypeRef/SingletonType -- the latter would make the polytype a type constructor)
728726
*/
729727
protected def readType()(using Context): Type = {
728+
def select(pre: Type, sym: Symbol): Type =
729+
// structural members need to be selected by name, their symbols are only
730+
// valid in the synthetic refinement class that defines them.
731+
if !pre.isInstanceOf[ThisType] && isRefinementClass(sym.owner) then pre.select(sym.name) else pre.select(sym)
732+
730733
val tag = readByte()
731734
val end = readNat() + readIndex
732735
(tag: @switch) match {
@@ -739,7 +742,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
739742
case SINGLEtpe =>
740743
val pre = readPrefix()
741744
val sym = readDisambiguatedSymbolRef(_.info.isParameterless)
742-
pre.select(sym)
745+
select(pre, sym)
743746
case SUPERtpe =>
744747
val thistpe = readTypeRef()
745748
val supertpe = readTypeRef()
@@ -770,7 +773,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
770773
pre = sym.owner.thisType
771774
case _ =>
772775
}
773-
val tycon = pre.select(sym)
776+
val tycon = select(pre, sym)
774777
val args = until(end, () => readTypeRef())
775778
if (sym == defn.ByNameParamClass2x) ExprType(args.head)
776779
else if (args.nonEmpty) tycon.safeAppliedTo(EtaExpandIfHK(sym.typeParams, args.map(translateTempPoly)))
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
val scala3Version = sys.props("plugin.scalaVersion")
2+
val scala2Version = "2.13.5"
3+
4+
lazy val lib = (project in file ("lib"))
5+
.settings(scalaVersion := scala2Version)
6+
7+
lazy val test = (project in file ("main"))
8+
.dependsOn(lib)
9+
.settings(scalaVersion := scala3Version)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class D
2+
object Scala2 {
3+
val structural1: { type DSub <: D; val member: Int } = new { type DSub <: D; val member: Int = 1 }
4+
val dsub: structural1.DSub = null.asInstanceOf[structural1.DSub]
5+
val mbr: structural1.member.type = structural1.member
6+
7+
def a(a: structural1.DSub): Unit = {}
8+
9+
def b(a: structural1.member.type): Unit = {}
10+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
object Test extends App {
2+
Scala2.a(Scala2.dsub)
3+
Scala2.b(Scala2.mbr)
4+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % sys.props("plugin.version"))
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
> test/run

0 commit comments

Comments
 (0)