diff options
author | Martin Odersky <odersky@gmail.com> | 2008-08-05 12:08:02 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2008-08-05 12:08:02 +0000 |
commit | f65e13b82d74443728175a4649ddf324c166dcbf (patch) | |
tree | 697a1286b0d759e6dd41f06355c644b3b06d1b15 | |
parent | d850636479c5d1b192c5239d9a5ca7bc0bd82385 (diff) | |
download | scala-f65e13b82d74443728175a4649ddf324c166dcbf.tar.gz scala-f65e13b82d74443728175a4649ddf324c166dcbf.tar.bz2 scala-f65e13b82d74443728175a4649ddf324c166dcbf.zip |
fixed #1096, #1122, #1132.
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/StdNames.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Symbols.scala | 13 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Types.scala | 18 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala | 118 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 14 | ||||
-rw-r--r-- | test/files/pos/t1159.scala | 13 |
6 files changed, 165 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala index 8385b13dfb..bac2f89328 100644 --- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala +++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala @@ -291,6 +291,7 @@ trait StdNames { val coerce = newTermName("coerce") val defaultValue = newTermName("defaultValue") val detach = newTermName("detach") + val dottype = newTermName(".type") val drop = newTermName("drop") val dummy = newTermName("$dummy") val elem = newTermName("elem") diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index 2baeee7fff..59854137ed 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -1280,14 +1280,15 @@ trait Symbols { private def compose(ss: List[String]): String = ss.filter("" !=).mkString("", " ", "") + def isSingletonExistential: Boolean = + (name endsWith nme.dottype) && (info.bounds.hi.typeSymbol isSubClass SingletonClass) + /** String representation of existentially bound variable */ - def existentialToString = { - val tname = name.toString - if ((tname endsWith ".type") && (info.bounds.hi.typeSymbol isSubClass SingletonClass) && - !settings.debug.value) - "val "+tname.substring(0, tname.length - 5)+": "+dropSingletonType(info.bounds.hi) + def existentialToString = + if (isSingletonExistential && !settings.debug.value) + "val "+name.subName(0, name.length - nme.dottype.length)+": "+ + dropSingletonType(info.bounds.hi) else defString - } } /** A class for term symbols */ diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index fe36c0a3b4..93eb31ad3d 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -1691,7 +1691,25 @@ A type's typeSymbol should never be inspected directly. underlying.substSym(quantified, skolems) } + private def wildcardArgsString(available: Set[Symbol], args: List[Type]): List[String] = args match { + case TypeRef(_, sym, _) :: args1 if (quantified contains sym) => + ("_"+sym.infoString(sym.info)) :: wildcardArgsString(available - sym, args1) + case arg :: args1 if !(quantified exists (arg contains _)) => + arg.toString :: wildcardArgsString(available, args1) + case _ => + List() + } + override def safeToString: String = { + if (!(quantified exists (_.isSingletonExistential)) && !settings.debug.value) + // try to represent with wildcards first + underlying match { + case TypeRef(pre, sym, args) if (!args.isEmpty) => + val wargs = wildcardArgsString(Predef.Set()++quantified, args) + if (wargs.length == args.length) + return TypeRef(pre, sym, List()).toString+wargs.mkString("[", ", ", "]") + case _ => + } var ustr = underlying.toString underlying match { case MethodType(_, _) | PolyType(_, _) => ustr = "("+ustr+")" diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index 09799d4412..de4854b1e2 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -22,6 +22,8 @@ import PickleFormat._ abstract class Pickler extends SubComponent { import global._ + private final val showSig = false + val phaseName = "pickler" def newPhase(prev: Phase): StdPhase = new PicklePhase(prev) @@ -943,14 +945,126 @@ abstract class Pickler extends SubComponent { patchNat(startpos + 1, writeIndex - (startpos + 2)) } + /** Print entry for diagnostics */ + private def printEntry(entry: AnyRef) { + def printRef(ref: AnyRef) { + print(index(ref)+ + (if (ref.isInstanceOf[Name]) "("+ref+") " else " ")) + } + def printRefs(refs: List[AnyRef]) { refs foreach printRef } + def printSymInfo(sym: Symbol) { + var posOffset = 0 + printRef(sym.name) + printRef(normalizedOwner(sym)) + print(flagsToString(sym.flags & PickledFlags)+" ") + if (sym.privateWithin != NoSymbol) printRef(sym.privateWithin) + printRef(sym.info) + } + def printBody(entry: AnyRef) = entry match { + case name: Name => + print((if (name.isTermName) "TERMname " else "TYPEname ")+name) + case NoSymbol => + print("NONEsym") + case sym: Symbol if !isLocal(sym) => + if (sym.isModuleClass) { + print("EXTMODCLASSref "); printRef(sym.name.toTermName) + } else { + print("EXTref "); printRef(sym.name) + } + if (!sym.owner.isRoot) printRef(sym.owner) + case sym: ClassSymbol => + print("CLASSsym ") + printSymInfo(sym) + if (sym.thisSym.tpe != sym.tpe) printRef(sym.typeOfThis) + case sym: TypeSymbol => + print(if (sym.isAbstractType) "TYPEsym " else "ALIASsym ") + printSymInfo(sym) + case sym: TermSymbol => + print(if (sym.isModule) "MODULEsym " else "VALsym ") + printSymInfo(sym) + if (sym.alias != NoSymbol) printRef(sym.alias) + case NoType => + print("NOtpe") + case NoPrefix => + print("NOPREFIXtpe") + case ThisType(sym) => + print("THIStpe "); printRef(sym) + case SingleType(pre, sym) => + print("SINGLEtpe "); printRef(pre); printRef(sym); + case ConstantType(value) => + print("CONSTANTtpe "); printRef(value); + case TypeRef(pre, sym, args) => + print("TYPEREFtpe "); printRef(pre); printRef(sym); printRefs(args); + case TypeBounds(lo, hi) => + print("TYPEBOUNDStpe "); printRef(lo); printRef(hi); + case tp @ RefinedType(parents, decls) => + print("REFINEDtpe "); printRef(tp.typeSymbol); printRefs(parents); + case ClassInfoType(parents, decls, clazz) => + print("CLASSINFOtpe "); printRef(clazz); printRefs(parents); + case MethodType(formals, restpe) => + print(if (entry.isInstanceOf[ImplicitMethodType]) "IMPLICITMETHODtpe " else "METHODtpe "); + printRef(restpe); printRefs(formals) + case PolyType(tparams, restpe) => + print("POLYtpe "); printRef(restpe); printRefs(tparams); + case ExistentialType(tparams, restpe) => + print("EXISTENTIALtpe "); printRef(restpe); printRefs(tparams); + case DeBruijnIndex(l, i) => + print("DEBRUIJNINDEXtpe "); print(l+" "+i) + case c @ Constant(_) => + print("LITERAL ") + if (c.tag == BooleanTag) print("Boolean "+(if (c.booleanValue) 1 else 0)) + else if (c.tag == ByteTag) print("Byte "+c.longValue) + else if (c.tag == ShortTag) print("Short "+c.longValue) + else if (c.tag == CharTag) print("Char "+c.longValue) + else if (c.tag == IntTag) print("Int "+c.longValue) + else if (c.tag == LongTag) print("Long "+c.longValue) + else if (c.tag == FloatTag) print("Float "+c.floatValue) + else if (c.tag == DoubleTag) print("Double "+c.doubleValue) + else if (c.tag == StringTag) { print("String "); printRef(newTermName(c.stringValue)) } + else if (c.tag == ClassTag) { print("Class "); printRef(c.typeValue) } + case AnnotatedType(attribs, tp, selfsym) => + if (settings.selfInAnnots.value) { + print("ANNOTATEDWSELFtpe ") + printRef(tp) + printRef(selfsym) + printRefs(attribs) + } else { + print("ANNOTATEDtpe ") + printRef(tp) + printRefs(attribs) + } + case (target: Symbol, attr @ AnnotationInfo(atp, args, assocs)) => + print("ATTRIBUTE ") + printRef(target) + printRef(atp) + for (c <- args) printRef(c) + for ((name, c) <- assocs) { printRef(name); printRef(c) } + case (target: Symbol, children: List[_]) => + print("CHILDREN ") + printRef(target) + for (c <- children) printRef(c.asInstanceOf[Symbol]) + case _ => + throw new FatalError("bad entry: " + entry + " " + entry.getClass) + } + printBody(entry); println() + } + /** Write byte array */ def finish { assert(writeIndex == 0) writeNat(MajorVersion) writeNat(MinorVersion) writeNat(ep) - if (settings.debug.value) log("" + ep + " entries")//debug - for (i <- 0 until ep) writeEntry(entries(i)) + if (showSig) { + println("Pickled info for "+rootName+" V"+MajorVersion+"."+MinorVersion) + } + for (i <- 0 until ep) { + if (showSig) { + print((i formatted "%3d: ")+(writeIndex formatted "%5d: ")) + printEntry(entries(i)) + } + writeEntry(entries(i)) + } if (settings.Xshowcls.value == rootName.toString) { readIndex = 0 ShowPickled.printFile(this, Console.out) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index f93848100d..486dc1c36c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1647,7 +1647,7 @@ trait Typers { self: Analyzer => lastarg.pos, "I'm seeing an array passed into a Java vararg.\n"+ "I assume that the elements of this array should be passed as individual arguments to the vararg.\n"+ - "Therefore I wrap the array in a `: _*', to mark it as a vararg argument.\n"+ + "Therefore I follow the array with a `: _*', to mark it as a vararg argument.\n"+ "If that's not what you want, compile this file with option -Xno-varargs-conversion.") args0 = args.init ::: List(gen.wildcardStar(args.last)) } @@ -2028,6 +2028,9 @@ trait Typers { self: Analyzer => } } + def isRawParameter(sym: Symbol) = // is it a type parameter leaked by a raw type? + sym.isTypeParameter && sym.owner.hasFlag(JAVA) + /** Given a set `rawSyms' of term- and type-symbols, and a type `tp'. * produce a set of fresh type parameters and a type so that it can be * abstracted to an existential type. @@ -2048,8 +2051,8 @@ trait Typers { self: Analyzer => val typeParams: List[Symbol] = rawSyms map { sym => val name = if (sym.isType) sym.name else newTypeName(sym.name+".type") val bound = sym.existentialBound - val quantified: Symbol = - recycle(sym.owner.newAbstractType(sym.pos, name)) + val sowner = if (isRawParameter(sym)) context.owner else sym.owner + val quantified: Symbol = recycle(sowner.newAbstractType(sym.pos, name)) trackSetInfo(quantified setFlag EXISTENTIAL)(bound.cloneInfo(quantified)) } val typeParamTypes = typeParams map (_.tpe) // don't trackSetInfo here, since type already set! @@ -2101,7 +2104,7 @@ trait Typers { self: Analyzer => def isLocal(sym: Symbol): Boolean = if (sym == NoSymbol) false else if (owner == NoSymbol) tree exists (defines(_, sym)) - else containsDef(owner, sym) + else containsDef(owner, sym) || isRawParameter(sym) def containsLocal(tp: Type): Boolean = tp exists (t => isLocal(t.typeSymbol) || isLocal(t.termSymbol)) val normalizeLocals = new TypeMap { @@ -2673,6 +2676,8 @@ trait Typers { self: Analyzer => case Ident(_) => mkAssign(qual) } + typed1(tree1, mode, pt) +/* if (settings.debug.value) log("retry assign: "+tree1) silent(_.typed1(tree1, mode, pt)) match { case t: Tree => @@ -2681,6 +2686,7 @@ trait Typers { self: Analyzer => reportTypeError(tree.pos, ex) setError(tree) } +*/ } def typedSuper(qual: Name, mix: Name) = { diff --git a/test/files/pos/t1159.scala b/test/files/pos/t1159.scala new file mode 100644 index 0000000000..7e09418b28 --- /dev/null +++ b/test/files/pos/t1159.scala @@ -0,0 +1,13 @@ +object test17 { + def main(args : Array[String]) = { + val value = + if (false) + new java.lang.Float(0) + else if (false) + new java.lang.Long(0) + else + new java.lang.Integer(0) + + println(value) + } +} |