diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2012-07-01 12:42:42 +0200 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2012-07-01 12:54:12 +0200 |
commit | ad51d8295388c02ca9160177aaba1b7e490eb5c2 (patch) | |
tree | a532bdebce0f4b3ef316fa3635e684b927710b71 /src/reflect | |
parent | 0a9cea6ea58571deb67d60193d60d12be6bb0233 (diff) | |
download | scala-ad51d8295388c02ca9160177aaba1b7e490eb5c2.tar.gz scala-ad51d8295388c02ca9160177aaba1b7e490eb5c2.tar.bz2 scala-ad51d8295388c02ca9160177aaba1b7e490eb5c2.zip |
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`.
Diffstat (limited to 'src/reflect')
-rw-r--r-- | src/reflect/scala/reflect/internal/Symbols.scala | 38 |
1 files changed, 21 insertions, 17 deletions
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index a3893a0236..79041924a8 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -1438,24 +1438,28 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ def classBound: Type = { val tp = refinedType(info.parents, owner) - val thistp = tp.typeSymbol.thisType - val oldsymbuf = new ListBuffer[Symbol] - val newsymbuf = new ListBuffer[Symbol] - for (sym <- info.decls) { - // todo: what about public references to private symbols? - if (sym.isPublic && !sym.isConstructor) { - oldsymbuf += sym - newsymbuf += ( - if (sym.isClass) - tp.typeSymbol.newAbstractType(sym.name.toTypeName, sym.pos).setInfo(sym.existentialBound) - else - sym.cloneSymbol(tp.typeSymbol)) + // SI-4589 refinedType only creates a new refinement class symbol before erasure; afterwards + // the first parent class is returned, to which we must not add members. + if (!phase.erasedTypes) { + val thistp = tp.typeSymbol.thisType + val oldsymbuf = new ListBuffer[Symbol] + val newsymbuf = new ListBuffer[Symbol] + for (sym <- info.decls) { + // todo: what about public references to private symbols? + if (sym.isPublic && !sym.isConstructor) { + oldsymbuf += sym + newsymbuf += ( + if (sym.isClass) + tp.typeSymbol.newAbstractType(sym.name.toTypeName, sym.pos).setInfo(sym.existentialBound) + else + sym.cloneSymbol(tp.typeSymbol)) + } + } + val oldsyms = oldsymbuf.toList + val newsyms = newsymbuf.toList + for (sym <- newsyms) { + addMember(thistp, tp, sym modifyInfo (_ substThisAndSym(this, thistp, oldsyms, newsyms))) } - } - val oldsyms = oldsymbuf.toList - val newsyms = newsymbuf.toList - for (sym <- newsyms) { - addMember(thistp, tp, sym modifyInfo (_ substThisAndSym(this, thistp, oldsyms, newsyms))) } tp } |