Skip to content

Commit 71bf783

Browse files
committed
Clean up accesses to Scala-2 inner classes
Since these can shadow each other, we need to refer to them by a name and a namespace. This is more solid than the system it replaces, which referred to such symbols symbplically but then fell back to the (unsafe) simple name on pickling.
1 parent 5b384f0 commit 71bf783

File tree

2 files changed

+8
-13
lines changed

2 files changed

+8
-13
lines changed

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,6 @@ class TreePickler(pickler: TastyPickler) {
144144
pickleConstant(value)
145145
case tpe: NamedType =>
146146
val sym = tpe.symbol
147-
def pickleStdRef(name: Name) = {
148-
writeByte(if (tpe.isType) TYPEREF else TERMREF)
149-
pickleName(name); pickleType(tpe.prefix)
150-
}
151147
def pickleDirectRef() = {
152148
writeByte(if (tpe.isType) TYPEREFdirect else TERMREFdirect)
153149
pickleSymRef(sym)
@@ -172,12 +168,9 @@ class TreePickler(pickler: TastyPickler) {
172168
pickleSymRef(sym); pickleType(tpe.prefix)
173169
}
174170
else tpe.designator match {
175-
case sym: Symbol =>
176-
assert(tpe.symbol.isClass && tpe.symbol.is(Flags.Scala2x), tpe.symbol.showLocated)
177-
// Note: vulnerability here, since Scala2x allows several classes with same name and prefix
178-
pickleStdRef(sym.name)
179171
case name: Name =>
180-
pickleStdRef(name)
172+
writeByte(if (tpe.isType) TYPEREF else TERMREF)
173+
pickleName(name); pickleType(tpe.prefix)
181174
case LocalName(name, space) =>
182175
writeByte(if (tpe.isType) TYPEREFin else TERMREFin)
183176
withLength {

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -733,14 +733,16 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
733733
case _ =>
734734
}
735735
val tycon =
736-
if (sym.isClass && sym.is(Scala2x) && !sym.owner.is(Package))
737-
// use fixed sym for Scala 2 inner classes, because they might be shadowed
738-
TypeRef(pre, sym.asType)
736+
if (sym.isClass && sym.is(Scala2x) && sym.owner.isClass && !sym.owner.is(Package))
737+
// There can be multiple Scala2 inner classes with the same prefix and name; use a namespace
738+
// to pick a particular one.
739+
TypeRef(pre, sym.name.asTypeName.withNameSpace(sym.owner.typeRef))
739740
else if (isLocal(sym) || pre == NoPrefix) {
740741
val pre1 = if ((pre eq NoPrefix) && (sym is TypeParam)) sym.owner.thisType else pre
741742
pre1 select sym
742743
}
743-
else TypeRef(pre, sym.name.asTypeName)
744+
else
745+
TypeRef(pre, sym.name.asTypeName)
744746
val args = until(end, readTypeRef)
745747
if (sym == defn.ByNameParamClass2x) ExprType(args.head)
746748
else if (args.nonEmpty) tycon.safeAppliedTo(EtaExpandIfHK(sym.typeParams, args.map(translateTempPoly)))

0 commit comments

Comments
 (0)