From e869cd34104701f8c55e19c542775679a1802edd Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 26 Feb 2008 09:50:05 +0000 Subject: fixed #520, #489 --- .../nsc/symtab/classfile/ClassfileParser.scala | 6 ++---- .../scala/tools/nsc/symtab/classfile/Pickler.scala | 23 ++++++++++++++------- test/files/neg/t0528neg.check | 4 ++++ test/files/neg/t0528neg.scala | 15 ++++++++++++++ test/files/run/t0412.check | 2 ++ test/files/run/t0412.scala | 4 ++++ test/files/run/t0528.check | Bin 0 -> 47 bytes test/files/run/t0528.scala | 14 +++++++++++++ 8 files changed, 57 insertions(+), 11 deletions(-) create mode 100644 test/files/neg/t0528neg.check create mode 100644 test/files/neg/t0528neg.scala create mode 100644 test/files/run/t0412.check create mode 100644 test/files/run/t0412.scala create mode 100644 test/files/run/t0528.check create mode 100644 test/files/run/t0528.scala diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 991808bad0..b510b41c4b 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -521,9 +521,8 @@ abstract class ClassfileParser { while (sig(index) == '.') { accept('.') val name = subName(c => c == ';' || c == '.').toTypeName - val clazz = tpe.typeSymbol.info.member(name) - assert(clazz.isClass, - tpe.typeSymbol.linkedModuleOfClass.moduleClass.info+" "+tpe+" . "+name+"/"+tpe.typeSymbol.info.decls) + val clazz = tpe.member(name) + assert(clazz.isAliasType, tpe) tpe = processClassType(clazz.tpe) } accept(';') @@ -747,7 +746,6 @@ abstract class ClassfileParser { val nameIndex = in.nextChar val jflags = in.nextChar if (innerIndex != 0 && outerIndex != 0 && nameIndex != 0 && - (jflags & (JAVA_ACC_PUBLIC | JAVA_ACC_PROTECTED)) != 0 && pool.getClassSymbol(outerIndex) == sym) { makeInnerAlias( getOwner(jflags), diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index 6bb7ec7369..20299dfc2a 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -43,7 +43,7 @@ abstract class Pickler extends SubComponent { stats foreach pickle case ClassDef(_, _, _, _) | ModuleDef(_, _, _) => val sym = tree.symbol - val pickle = new Pickle(sym.name.toTermName, sym.owner) + val pickle = new Pickle(sym, sym.name.toTermName, sym.owner) add(sym, pickle) add(sym.linkedSym, pickle) pickle.finish @@ -62,23 +62,32 @@ abstract class Pickler extends SubComponent { } } - private class Pickle(rootName: Name, rootOwner: Symbol) + private class Pickle(root: Symbol, rootName: Name, rootOwner: Symbol) extends PickleBuffer(new Array[Byte](4096), -1, 0) { import scala.collection.jcl.LinkedHashMap private var entries = new Array[AnyRef](256) private var ep = 0 private val index = new LinkedHashMap[AnyRef, Int] + /** Is symbol an existentially bound variable with a package as owner? + * Such symbols should be treated as if they were local. + */ + private def isUnrootedExistential(sym: Symbol) = + false && sym.isAbstractType && sym.hasFlag(EXISTENTIAL) && sym.owner.isPackageClass + + private def normalizedOwner(sym: Symbol) = + if (isUnrootedExistential(sym)) root else sym.owner + /** Is root in symbol.owner*? * * @param sym ... * @return ... */ - private def isLocal(sym: Symbol): Boolean = ( + private def isLocal(sym: Symbol): Boolean = sym.isRefinementClass || sym.name.toTermName == rootName && sym.owner == rootOwner || - sym != NoSymbol && isLocal(sym.owner) - ) + sym != NoSymbol && isLocal(sym.owner) || + isUnrootedExistential(sym) // Phase 1 methods: Populate entries/index ------------------------------------ @@ -455,7 +464,7 @@ abstract class Pickler extends SubComponent { private def writeSymInfo(sym: Symbol): Int = { var posOffset = 0 writeRef(sym.name) - writeRef(sym.owner) + writeRef(normalizedOwner(sym)) writeNat((sym.flags & PickledFlags).asInstanceOf[Int]) if (sym.privateWithin != NoSymbol) writeRef(sym.privateWithin) writeRef(sym.info) @@ -483,7 +492,7 @@ abstract class Pickler extends SubComponent { } else { writeRef(sym.name); EXTref } - if (!sym.owner.isRoot) writeRef(sym.owner); + if (!sym.owner.isRoot) writeRef(sym.owner) tag case sym: ClassSymbol => val posOffset = writeSymInfo(sym) diff --git a/test/files/neg/t0528neg.check b/test/files/neg/t0528neg.check new file mode 100644 index 0000000000..c8c3ab422f --- /dev/null +++ b/test/files/neg/t0528neg.check @@ -0,0 +1,4 @@ +t0528neg.scala:2: error: covariant type A occurs in invariant position in type => Array[T forSome { type T <: A }] of method toArray + def toArray: Array[T forSome {type T <: A}] + ^ +one error found diff --git a/test/files/neg/t0528neg.scala b/test/files/neg/t0528neg.scala new file mode 100644 index 0000000000..911745b763 --- /dev/null +++ b/test/files/neg/t0528neg.scala @@ -0,0 +1,15 @@ +trait Sequ[+A] { + def toArray: Array[T forSome {type T <: A}] +} + +class RichStr extends Sequ[Char] { + // override to a primitve array + def toArray: Array[Char] = new Array[Char](10) +} + +object Foo extends Application { + val x: RichStr = new RichStr + + println(x.toArray) // call directly + println((x: Sequ[Char]).toArray) // calling through the bridge misses unboxing +} diff --git a/test/files/run/t0412.check b/test/files/run/t0412.check new file mode 100644 index 0000000000..c7141ddbd9 --- /dev/null +++ b/test/files/run/t0412.check @@ -0,0 +1,2 @@ +class java.util.ArrayList +class java.util.ArrayList diff --git a/test/files/run/t0412.scala b/test/files/run/t0412.scala new file mode 100644 index 0000000000..f1ca7379ae --- /dev/null +++ b/test/files/run/t0412.scala @@ -0,0 +1,4 @@ +object Test extends Application { + println(classOf[java.util.ArrayList[_]]) + println(classOf[java.util.ArrayList[T] forSome { type T }]) +} diff --git a/test/files/run/t0528.check b/test/files/run/t0528.check new file mode 100644 index 0000000000..b64e97a93a Binary files /dev/null and b/test/files/run/t0528.check differ diff --git a/test/files/run/t0528.scala b/test/files/run/t0528.scala new file mode 100644 index 0000000000..b00ef4fa92 --- /dev/null +++ b/test/files/run/t0528.scala @@ -0,0 +1,14 @@ +trait Sequ[A] { + def toArray: Array[T forSome {type T <: A}] +} + +class RichStr extends Sequ[Char] { + // override to a primitve array + def toArray: Array[Char] = Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') +} + +object Test extends Application { + val x: RichStr = new RichStr + + println((x: Sequ[Char]).toArray) // calling through the bridge misses unboxing +} -- cgit v1.2.3