summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2008-08-05 12:08:02 +0000
committerMartin Odersky <odersky@gmail.com>2008-08-05 12:08:02 +0000
commitf65e13b82d74443728175a4649ddf324c166dcbf (patch)
tree697a1286b0d759e6dd41f06355c644b3b06d1b15
parentd850636479c5d1b192c5239d9a5ca7bc0bd82385 (diff)
downloadscala-f65e13b82d74443728175a4649ddf324c166dcbf.tar.gz
scala-f65e13b82d74443728175a4649ddf324c166dcbf.tar.bz2
scala-f65e13b82d74443728175a4649ddf324c166dcbf.zip
fixed #1096, #1122, #1132.
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala13
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala18
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala118
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala14
-rw-r--r--test/files/pos/t1159.scala13
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)
+ }
+}