Skip to content

Commit ad51d82

Browse files
committed
SI-5489 Avoid accidentally adding members to Object in erasure.
`Symbol#classBound` assumed that `refinedType` would return a a type based on new refinement class symbol; but that isn't so during erasure. Instead, it returns the first super class, into which we entered new members. Needless to say, the next run of the resident compiler didn't take kindly to these hijinks. To remedy the situation, I've added (yet another) condition on `phase.erasedTypes`.
1 parent 0a9cea6 commit ad51d82

File tree

4 files changed

+41
-17
lines changed

4 files changed

+41
-17
lines changed

src/reflect/scala/reflect/internal/Symbols.scala

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,24 +1438,28 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
14381438
*/
14391439
def classBound: Type = {
14401440
val tp = refinedType(info.parents, owner)
1441-
val thistp = tp.typeSymbol.thisType
1442-
val oldsymbuf = new ListBuffer[Symbol]
1443-
val newsymbuf = new ListBuffer[Symbol]
1444-
for (sym <- info.decls) {
1445-
// todo: what about public references to private symbols?
1446-
if (sym.isPublic && !sym.isConstructor) {
1447-
oldsymbuf += sym
1448-
newsymbuf += (
1449-
if (sym.isClass)
1450-
tp.typeSymbol.newAbstractType(sym.name.toTypeName, sym.pos).setInfo(sym.existentialBound)
1451-
else
1452-
sym.cloneSymbol(tp.typeSymbol))
1441+
// SI-4589 refinedType only creates a new refinement class symbol before erasure; afterwards
1442+
// the first parent class is returned, to which we must not add members.
1443+
if (!phase.erasedTypes) {
1444+
val thistp = tp.typeSymbol.thisType
1445+
val oldsymbuf = new ListBuffer[Symbol]
1446+
val newsymbuf = new ListBuffer[Symbol]
1447+
for (sym <- info.decls) {
1448+
// todo: what about public references to private symbols?
1449+
if (sym.isPublic && !sym.isConstructor) {
1450+
oldsymbuf += sym
1451+
newsymbuf += (
1452+
if (sym.isClass)
1453+
tp.typeSymbol.newAbstractType(sym.name.toTypeName, sym.pos).setInfo(sym.existentialBound)
1454+
else
1455+
sym.cloneSymbol(tp.typeSymbol))
1456+
}
1457+
}
1458+
val oldsyms = oldsymbuf.toList
1459+
val newsyms = newsymbuf.toList
1460+
for (sym <- newsyms) {
1461+
addMember(thistp, tp, sym modifyInfo (_ substThisAndSym(this, thistp, oldsyms, newsyms)))
14531462
}
1454-
}
1455-
val oldsyms = oldsymbuf.toList
1456-
val newsyms = newsymbuf.toList
1457-
for (sym <- newsyms) {
1458-
addMember(thistp, tp, sym modifyInfo (_ substThisAndSym(this, thistp, oldsyms, newsyms)))
14591463
}
14601464
tp
14611465
}

test/files/res/t5489.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
nsc>
3+
nsc>
4+
nsc>

test/files/res/t5489.res

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
t5489/t5489.scala
2+
t5489/t5489.scala

test/files/res/t5489/t5489.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package repro
2+
3+
trait HasString {
4+
def blerg(): String
5+
}
6+
7+
class CausesProblems {
8+
def problems = (
9+
if ("don't optimize me away!".length == 0)
10+
new HasString { def blerg() = "wut" }
11+
else
12+
new HasString { def blerg() = "okay" }
13+
).blerg()
14+
}

0 commit comments

Comments
 (0)