summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2012-05-23 11:01:19 -0700
committerAdriaan Moors <adriaan.moors@epfl.ch>2012-05-23 11:01:19 -0700
commit019c7aa2f6440e2b99066da464e0c48e9f83c74e (patch)
tree60b88adaa566c74cc7960b0f6d3bb58026cd42e2
parentc28a8588e10187a5c1dd03dbc677da19ed7205f8 (diff)
parentf026bbb2ee1d1f9bed8c3a401833bb535b856f6b (diff)
downloadscala-019c7aa2f6440e2b99066da464e0c48e9f83c74e.tar.gz
scala-019c7aa2f6440e2b99066da464e0c48e9f83c74e.tar.bz2
scala-019c7aa2f6440e2b99066da464e0c48e9f83c74e.zip
Merge pull request #607 from paulp/may22-checkin
tests and misc improvements
-rw-r--r--src/compiler/scala/reflect/internal/InfoTransformers.scala4
-rw-r--r--src/compiler/scala/reflect/internal/Phase.scala10
-rw-r--r--src/compiler/scala/reflect/internal/util/Origins.scala86
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala4
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/AddInterfaces.scala3
-rw-r--r--src/compiler/scala/tools/nsc/transform/InfoTransform.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala17
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala25
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala67
-rw-r--r--test/files/neg/t963b.check6
-rw-r--r--test/files/neg/t963b.scala (renamed from test/pending/neg/t963.scala)6
-rw-r--r--test/files/pos/arrays3.scala11
-rw-r--r--test/files/pos/t5809.flags1
-rw-r--r--test/files/pos/t5809.scala10
-rw-r--r--test/files/pos/z1730.flags1
-rw-r--r--test/files/pos/z1730.scala13
-rw-r--r--test/files/run/origins.check2
-rw-r--r--test/files/run/origins.scala2
-rw-r--r--test/pending/neg/t5008.scala165
-rw-r--r--test/pending/pos/t4649.flags1
-rw-r--r--test/pending/pos/t4649.scala6
-rw-r--r--test/pending/run/partial-anyref-spec.check13
-rw-r--r--test/pending/run/partial-anyref-spec.scala31
26 files changed, 378 insertions, 113 deletions
diff --git a/src/compiler/scala/reflect/internal/InfoTransformers.scala b/src/compiler/scala/reflect/internal/InfoTransformers.scala
index 96d9d8f076..e53f714c0c 100644
--- a/src/compiler/scala/reflect/internal/InfoTransformers.scala
+++ b/src/compiler/scala/reflect/internal/InfoTransformers.scala
@@ -20,12 +20,14 @@ trait InfoTransformers {
def transform(sym: Symbol, tpe: Type): Type
def insert(that: InfoTransformer) {
- assert(this.pid != that.pid)
+ assert(this.pid != that.pid, this.pid)
+
if (that.pid < this.pid) {
prev insert that
} else if (next.pid <= that.pid && next.pid != NoPhase.id) {
next insert that
} else {
+ log("Inserting info transformer %s following %s".format(phaseOf(that.pid), phaseOf(this.pid)))
that.next = next
that.prev = this
next.prev = that
diff --git a/src/compiler/scala/reflect/internal/Phase.scala b/src/compiler/scala/reflect/internal/Phase.scala
index 89d643aacf..68dc5ce783 100644
--- a/src/compiler/scala/reflect/internal/Phase.scala
+++ b/src/compiler/scala/reflect/internal/Phase.scala
@@ -7,9 +7,10 @@ package scala.reflect
package internal
abstract class Phase(val prev: Phase) {
+ if ((prev ne null) && (prev ne NoPhase))
+ prev.nx = this
type Id = Int
-
val id: Id = if (prev eq null) 0 else prev.id + 1
/** New flags visible after this phase has completed */
@@ -18,12 +19,13 @@ abstract class Phase(val prev: Phase) {
/** New flags visible once this phase has started */
def newFlags: Long = 0l
- private var fmask: Long =
- if (prev eq null) Flags.InitialFlags else prev.flagMask | prev.nextFlags | newFlags
+ val fmask = (
+ if (prev eq null) Flags.InitialFlags
+ else prev.flagMask | prev.nextFlags | newFlags
+ )
def flagMask: Long = fmask
private var nx: Phase = this
- if ((prev ne null) && (prev ne NoPhase)) prev.nx = this
def next: Phase = nx
def hasNext = next != this
diff --git a/src/compiler/scala/reflect/internal/util/Origins.scala b/src/compiler/scala/reflect/internal/util/Origins.scala
index 19b3adda9d..0bd5ad55ca 100644
--- a/src/compiler/scala/reflect/internal/util/Origins.scala
+++ b/src/compiler/scala/reflect/internal/util/Origins.scala
@@ -15,7 +15,7 @@ import Origins._
* You could do this:
*
* {{{
- * private lazy val origins = Origins[SymbolTable]("phase_=")
+ * private lazy val origins = Origins("arbitraryTag")
* // Commented out original enclosed for contrast
* // final def phase_=(p: Phase): Unit = {
* final def phase_=(p: Phase): Unit = origins {
@@ -23,7 +23,7 @@ import Origins._
*
* And that's it. When the JVM exits it would issue a report something like this:
{{{
- >> Origins scala.tools.nsc.symtab.SymbolTable.phase_= logged 145585 calls from 51 distinguished sources.
+ >> Origins tag 'arbitraryTag' logged 145585 calls from 51 distinguished sources.
71114 scala.tools.nsc.symtab.Symbols$Symbol.unsafeTypeParams(Symbols.scala:862)
16584 scala.tools.nsc.symtab.Symbols$Symbol.rawInfo(Symbols.scala:757)
@@ -37,29 +37,21 @@ import Origins._
*/
abstract class Origins {
type Rep
+ type StackSlice = Array[StackTraceElement]
+
+ def tag: String
+ def isCutoff(el: StackTraceElement): Boolean
def newRep(xs: StackSlice): Rep
def repString(rep: Rep): String
- def originClass: String
-
- private var _tag: String = null
- def tag: String = _tag
- def setTag(tag: String): this.type = {
- _tag = tag
- this
- }
private val origins = new mutable.HashMap[Rep, Int] withDefaultValue 0
private def add(xs: Rep) = origins(xs) += 1
private def total = origins.values.foldLeft(0L)(_ + _)
- // We find the right line by dropping any from around here and any
- // from the method's origin class.
- private def dropStackElement(cn: String) =
- (cn startsWith OriginsName) || (cn startsWith originClass)
-
// Create a stack and whittle it down to the interesting part.
- private def readStack(): Array[StackTraceElement] =
- (new Throwable).getStackTrace dropWhile (el => dropStackElement(el.getClassName))
+ def readStack(): Array[StackTraceElement] = (
+ Thread.currentThread.getStackTrace dropWhile (x => !isCutoff(x)) dropWhile isCutoff drop 1
+ )
def apply[T](body: => T): T = {
add(newRep(readStack()))
@@ -67,7 +59,7 @@ abstract class Origins {
}
def clear() = origins.clear()
def show() = {
- println("\n>> Origins %s.%s logged %s calls from %s distinguished sources.\n".format(originClass, tag, total, origins.keys.size))
+ println("\n>> Origins tag '%s' logged %s calls from %s distinguished sources.\n".format(tag, total, origins.keys.size))
origins.toList sortBy (-_._2) foreach {
case (k, v) => println("%7s %s".format(v, repString(k)))
}
@@ -79,29 +71,49 @@ abstract class Origins {
}
object Origins {
- private type StackSlice = Array[StackTraceElement]
- private val OriginsName = classOf[Origins].getName
- private val counters = new mutable.HashSet[Origins]
+ private val counters = mutable.HashMap[String, Origins]()
+ private val thisClass = this.getClass.getName
- {
- // Console.println("\nOrigins loaded: registering shutdown hook to display results.")
- sys.addShutdownHook(counters foreach (_.purge()))
+ locally {
+ sys.addShutdownHook(counters.values foreach (_.purge()))
}
- def apply[T: ClassTag](tag: String): Origins = apply(tag, classTag[T].erasure)
- def apply(tag: String, clazz: Class[_]): Origins = apply(tag, new OneLine(clazz))
- def apply(tag: String, orElse: => Origins): Origins = {
- counters find (_.tag == tag) getOrElse {
- val res = orElse setTag tag
- counters += res
- res
- }
+ case class OriginId(className: String, methodName: String) {
+ def matches(el: StackTraceElement) = (
+ (methodName == el.getMethodName) && (className startsWith el.getClassName)
+ )
}
- class OneLine(clazz: Class[_]) extends Origins {
- type Rep = StackTraceElement
- val originClass = clazz.getName stripSuffix MODULE_SUFFIX_STRING
- def newRep(xs: StackSlice): Rep = xs(0)
- def repString(rep: Rep) = " " + rep
+ def lookup(tag: String, orElse: String => Origins): Origins =
+ counters.getOrElseUpdate(tag, orElse(tag))
+ def register(x: Origins): Origins = {
+ counters(x.tag) = x
+ x
+ }
+
+ private def preCutoff(el: StackTraceElement) = (
+ (el.getClassName == thisClass)
+ || (el.getClassName startsWith "java.lang.")
+ )
+ private def findCutoff() = {
+ val cutoff = Thread.currentThread.getStackTrace dropWhile preCutoff head;
+ OriginId(cutoff.getClassName, cutoff.getMethodName)
+ }
+
+ def apply(tag: String): Origins = counters.getOrElseUpdate(tag, new OneLine(tag, findCutoff()))
+ def apply(tag: String, frames: Int): Origins = counters.getOrElseUpdate(tag, new MultiLine(tag, findCutoff(), frames))
+
+ class OneLine(val tag: String, id: OriginId) extends Origins {
+ type Rep = StackTraceElement
+ def isCutoff(el: StackTraceElement) = id matches el
+ def newRep(xs: StackSlice): Rep = if ((xs eq null) || (xs.length == 0)) null else xs(0)
+ def repString(rep: Rep) = " " + rep
+ }
+ class MultiLine(val tag: String, id: OriginId, numLines: Int) extends Origins {
+ type Rep = List[StackTraceElement]
+ def isCutoff(el: StackTraceElement) = id matches el
+ def newRep(xs: StackSlice): Rep = (xs take numLines).toList
+ def repString(rep: Rep) = rep.map("\n " + _).mkString
+ override def readStack() = super.readStack() drop 1
}
}
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index 23fcffd657..3a527676b4 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -208,6 +208,7 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL {
else AppliedTypeTree(Ident(clazz), targs map TypeTree)
))
}
+ def mkSuperSelect = Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR)
def wildcardStar(tree: Tree) =
atPos(tree.pos) { Typed(tree, Ident(tpnme.WILDCARD_STAR)) }
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index adc490c8e1..6f1a8f488f 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -115,9 +115,7 @@ trait Trees extends reflect.internal.Trees { self: Global =>
// convert (implicit ... ) to ()(implicit ... ) if its the only parameter section
if (vparamss1.isEmpty || !vparamss1.head.isEmpty && vparamss1.head.head.mods.isImplicit)
vparamss1 = List() :: vparamss1;
- val superRef: Tree = atPos(superPos) {
- Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR)
- }
+ val superRef: Tree = atPos(superPos)(gen.mkSuperSelect)
val superCall = (superRef /: argss) (Apply)
List(
atPos(wrappingPos(superPos, lvdefs ::: argss.flatten)) (
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index c02a7e493e..a0524d6932 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -385,7 +385,7 @@ self =>
Nil,
List(Nil),
TypeTree(),
- Block(List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), Nil)), Literal(Constant(())))
+ Block(List(Apply(gen.mkSuperSelect, Nil)), Literal(Constant(())))
)
// def main
diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
index cb7d64b9fc..e5fc98f23c 100644
--- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
@@ -308,8 +308,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
// body until now, because the typer knows that Any has no
// constructor and won't accept a call to super.init.
assert((clazz isSubClass AnyValClass) || clazz.info.parents.isEmpty, clazz)
- val superCall = Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), Nil)
- Block(List(superCall), expr)
+ Block(List(Apply(gen.mkSuperSelect, Nil)), expr)
case Block(stats, expr) =>
// needs `hasSymbol` check because `supercall` could be a block (named / default args)
diff --git a/src/compiler/scala/tools/nsc/transform/InfoTransform.scala b/src/compiler/scala/tools/nsc/transform/InfoTransform.scala
index 0905fa86c6..880f0f0157 100644
--- a/src/compiler/scala/tools/nsc/transform/InfoTransform.scala
+++ b/src/compiler/scala/tools/nsc/transform/InfoTransform.scala
@@ -37,7 +37,7 @@ trait InfoTransform extends Transform {
val changesBaseClasses = InfoTransform.this.changesBaseClasses
def transform(sym: Symbol, tpe: Type): Type = transformInfo(sym, tpe)
}
- infoTransformers.insert(infoTransformer)
+ infoTransformers insert infoTransformer
}
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 07a10ecb1f..f2e109a5ad 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -1388,26 +1388,23 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
tree
case Select(qual, name) =>
- debuglog("[%s] looking at Select: %s sym: %s: %s [tree.tpe: %s]".format(
- tree.pos.safeLine, tree, symbol, symbol.info, tree.tpe))
+ debuglog("specializing Select %s [tree.tpe: %s]".format(symbol.defString, tree.tpe))
//log("!!! select " + tree + " -> " + symbol.info + " specTypeVars: " + specializedTypeVars(symbol.info))
if (specializedTypeVars(symbol.info).nonEmpty && name != nme.CONSTRUCTOR) {
// log("!!! unifying " + (symbol, symbol.tpe) + " and " + (tree, tree.tpe))
val env = unify(symbol.tpe, tree.tpe, emptyEnv, false)
// log("!!! found env: " + env + "; overloads: " + overloads(symbol))
- debuglog("checking for rerouting: " + tree + " with sym.tpe: " + symbol.tpe + " tree.tpe: " + tree.tpe + " env: " + env)
if (!env.isEmpty) {
+ // debuglog("checking for rerouting: " + tree + " with sym.tpe: " + symbol.tpe + " tree.tpe: " + tree.tpe + " env: " + env)
val specMember = overload(symbol, env)
- //log("!!! found member: " + specMember)
if (specMember.isDefined) {
- // log("** routing " + tree + " to " + specMember.get.sym.fullName)
localTyper.typedOperator(atPos(tree.pos)(Select(transform(qual), specMember.get.sym.name)))
- } else {
+ }
+ else {
val qual1 = transform(qual)
val specMember = qual1.tpe.member(specializedName(symbol, env)).suchThat(_.tpe matches subst(env, symbol.tpe))
if (specMember ne NoSymbol) {
- // log("** using spec member " + specMember + ": " + specMember.tpe)
val tree1 = atPos(tree.pos)(Select(qual1, specMember))
if (specMember.isMethod)
localTyper.typedOperator(tree1)
@@ -1450,10 +1447,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
// log("--> method: " + ddef + " in " + ddef.symbol.owner + ", " + info(symbol))
if (symbol.isConstructor) {
- val t = atOwner(symbol) {
- val superRef: Tree = Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR)
- forwardCtorCall(tree.pos, superRef, vparamss, symbol.owner)
- }
+ val t = atOwner(symbol)(forwardCtorCall(tree.pos, gen.mkSuperSelect, vparamss, symbol.owner))
+
if (symbol.isPrimaryConstructor)
localTyper.typedPos(symbol.pos)(deriveDefDef(tree)(_ => Block(List(t), Literal(Constant()))))
else // duplicate the original constructor
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 2f2278251b..b4f42a5033 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -636,7 +636,7 @@ trait Namers extends MethodSynthesis {
classAndNamerOfModule(m) = (tree, null)
}
val owner = tree.symbol.owner
- if (settings.lint.value && owner.isPackageObjectClass) {
+ if (settings.lint.value && owner.isPackageObjectClass && !mods.isImplicit) {
context.unit.warning(tree.pos,
"it is not recommended to define classes/objects inside of package objects.\n" +
"If possible, define " + tree.symbol + " in " + owner.skipPackageObject + " instead."
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index d1f319311e..932e4548ef 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -260,19 +260,18 @@ trait NamesDefaults { self: Analyzer =>
def argValDefs(args: List[Tree], paramTypes: List[Type], blockTyper: Typer): List[ValDef] = {
val context = blockTyper.context
val symPs = map2(args, paramTypes)((arg, tpe) => {
- val byName = isByNameParamType(tpe)
- val (argTpe, repeated) =
- if (isScalaRepeatedParamType(tpe)) arg match {
- case Typed(expr, Ident(tpnme.WILDCARD_STAR)) =>
- (expr.tpe, true)
- case _ =>
- (seqType(arg.tpe), true)
- } else (arg.tpe, false)
- val s = context.owner.newValue(unit.freshTermName("x$"), arg.pos)
- val valType = if (byName) functionType(List(), argTpe)
- else if (repeated) argTpe
- else argTpe
- s.setInfo(valType)
+ val byName = isByNameParamType(tpe)
+ val repeated = isScalaRepeatedParamType(tpe)
+ val argTpe = (
+ if (repeated) arg match {
+ case Typed(expr, Ident(tpnme.WILDCARD_STAR)) => expr.tpe
+ case _ => seqType(arg.tpe)
+ }
+ else arg.tpe
+ ).widen // have to widen or types inferred from literal defaults will be singletons
+ val s = context.owner.newValue(unit.freshTermName("x$"), arg.pos) setInfo (
+ if (byName) functionType(Nil, argTpe) else argTpe
+ )
(context.scope.enter(s), byName, repeated)
})
map2(symPs, args) {
diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
index a6a8d6009f..fde760c752 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -14,22 +14,7 @@ import util.returning
abstract class TreeCheckers extends Analyzer {
import global._
- private val everything = ListBuffer[(Phase, Map[Tree, (Symbol, Type)])]()
- private val currentTrees = mutable.Map[Tree, (Symbol, Type)]()
- private val tpeOfTree = mutable.HashMap[Tree, Type]()
-
- if (settings.debug.value) {
- sys addShutdownHook {
- for ((ph, map) <- everything.toList) {
- println("\n>>>> " + ph + "\n")
- for ((tree, (sym, tpe)) <- map.toList.sortBy(_._1.summaryString)) {
- println("%20s %20s %s".format(sym, tpe, ("" + tree) take 50))
- }
- }
- }
- }
-
- private def classstr(x: AnyRef) = (x.getClass.getName split """\\.|\\$""").last
+ private def classstr(x: AnyRef) = x.getClass.getName split """\\.|\\$""" last;
private def typestr(x: Type) = " (tpe = " + x + ")"
private def treestr(t: Tree) = t + " [" + classstr(t) + "]" + typestr(t.tpe)
private def ownerstr(s: Symbol) = "'" + s + "'" + s.locationString
@@ -50,14 +35,13 @@ abstract class TreeCheckers extends Analyzer {
object SymbolTracker extends Traverser {
type PhaseMap = mutable.HashMap[Symbol, List[Tree]]
- val defSyms = mutable.HashMap[Symbol, List[DefTree]]() withDefaultValue Nil
- val newSyms = mutable.HashSet[Symbol]()
val maps = ListBuffer[(Phase, PhaseMap)]()
- val movedMsgs = ListBuffer[String]()
-
def prev = maps.init.last._2
def latest = maps.last._2
- def sortedNewSyms = newSyms.toList.distinct sortBy (_.name)
+ val defSyms = mutable.HashMap[Symbol, List[DefTree]]()
+ val newSyms = mutable.HashSet[Symbol]()
+ val movedMsgs = new ListBuffer[String]
+ def sortedNewSyms = newSyms.toList.distinct sortBy (_.name.toString)
def inPrev(sym: Symbol) = {
(maps.size >= 2) && (prev contains sym)
@@ -108,21 +92,18 @@ abstract class TreeCheckers extends Analyzer {
if (maps.isEmpty || maps.last._1 != ph)
maps += ((ph, new PhaseMap))
- currentTrees.clear()
traverse(unit.body)
- everything += ((ph, currentTrees.toMap))
-
reportChanges()
}
override def traverse(tree: Tree): Unit = {
val sym = tree.symbol
- currentTrees(tree) = ((sym, tree.tpe))
-
if (sym != null && sym != NoSymbol) {
record(sym, tree)
tree match {
- case x: DefTree => defSyms(sym) :+= x
- case _ => ()
+ case x: DefTree =>
+ if (defSyms contains sym) defSyms(sym) = defSyms(sym) :+ x
+ else defSyms(sym) = List(x)
+ case _ => ()
}
}
@@ -130,6 +111,8 @@ abstract class TreeCheckers extends Analyzer {
}
}
+ lazy val tpeOfTree = mutable.HashMap[Tree, Type]()
+
def posstr(p: Position) =
try p.source.path + ":" + p.line
catch { case _: UnsupportedOperationException => p.toString }
@@ -144,9 +127,20 @@ abstract class TreeCheckers extends Analyzer {
def assertFn(cond: Boolean, msg: => Any) =
if (!cond) errorFn(msg)
+ private def wrap[T](msg: => Any)(body: => Unit) {
+ try body
+ catch { case x =>
+ Console.println("Caught " + x)
+ Console.println(msg)
+ x.printStackTrace
+ }
+ }
+
def checkTrees() {
- informFn("[consistency check at the beginning of phase " + phase + "]")
- currentRun.units foreach check
+ if (settings.verbose.value)
+ Console.println("[consistency check at the beginning of phase " + phase + "]")
+
+ currentRun.units foreach (x => wrap(x)(check(x)))
}
def printingTypings[T](body: => T): T = {
@@ -168,7 +162,7 @@ abstract class TreeCheckers extends Analyzer {
informProgress("checking "+unit)
val context = rootContext(unit)
context.checking = true
- tpeOfTree.clear()
+ tpeOfTree.clear
SymbolTracker.check(phase, unit)
val checker = new TreeChecker(context)
runWithUnit(unit) {
@@ -215,11 +209,11 @@ abstract class TreeCheckers extends Analyzer {
tree.tpe = null
saved
})
- super.typed(tree, mode, pt) match {
+ wrap(tree)(super.typed(tree, mode, pt) match {
case _: Literal => ()
case x if x ne tree => treesDiffer(tree, x)
case _ => ()
- }
+ })
case _ => ()
}
@@ -286,7 +280,12 @@ abstract class TreeCheckers extends Analyzer {
if (sym.owner != currentOwner) {
val expected = currentOwner.ownerChain find (x => cond(x)) getOrElse fail("DefTree can't find owner: ")
if (sym.owner != expected)
- fail("Expected owner %s (out of %s), found %s: ".format(expected, currentOwner.ownerChain, sym.owner))
+ fail("""|
+ | currentOwner chain: %s
+ | symbol chain: %s""".stripMargin.format(
+ currentOwner.ownerChain take 3 mkString " -> ",
+ sym.ownerChain mkString " -> ")
+ )
}
}
}
diff --git a/test/files/neg/t963b.check b/test/files/neg/t963b.check
new file mode 100644
index 0000000000..9918a98c46
--- /dev/null
+++ b/test/files/neg/t963b.check
@@ -0,0 +1,6 @@
+t963b.scala:25: error: type mismatch;
+ found : B.type
+ required: AnyRef{val y: A}
+ B.f(B)
+ ^
+one error found
diff --git a/test/pending/neg/t963.scala b/test/files/neg/t963b.scala
index 3be0be1b84..b34aae8095 100644
--- a/test/pending/neg/t963.scala
+++ b/test/files/neg/t963b.scala
@@ -5,8 +5,8 @@ trait A {
}
object B {
- def f(x : { val y : A }) { x.y.v = x.y.v }
-
+ def f(x : { val y : A }) { x.y.v = x.y.v }
+
var a : A = _
var b : Boolean = false
def y : A = {
@@ -21,6 +21,6 @@ object B {
}
}
-object Test extends Application {
+object Test extends App {
B.f(B)
}
diff --git a/test/files/pos/arrays3.scala b/test/files/pos/arrays3.scala
new file mode 100644
index 0000000000..f96be0b427
--- /dev/null
+++ b/test/files/pos/arrays3.scala
@@ -0,0 +1,11 @@
+trait Foo {
+ type Repr <: String
+ def f2(x: Repr) = x.length
+}
+trait Fooz[Repr <: Array[_]] {
+ def f0(x: Repr) = x.length
+}
+
+trait Bar[Repr <: List[_]] extends Foo with Fooz[Array[Int]] {
+ def f1(x: Repr) = x.length
+}
diff --git a/test/files/pos/t5809.flags b/test/files/pos/t5809.flags
new file mode 100644
index 0000000000..e93641e931
--- /dev/null
+++ b/test/files/pos/t5809.flags
@@ -0,0 +1 @@
+-Xlint -Xfatal-warnings \ No newline at end of file
diff --git a/test/files/pos/t5809.scala b/test/files/pos/t5809.scala
new file mode 100644
index 0000000000..8f6ce708d2
--- /dev/null
+++ b/test/files/pos/t5809.scala
@@ -0,0 +1,10 @@
+package scala.reflect
+
+package object api {
+ implicit class PimpedExpr[T](expr: Universe # Expr[T]) {
+ def runtimeEval: T = {
+ println("hello, dear")
+ expr.eval
+ }
+ }
+} \ No newline at end of file
diff --git a/test/files/pos/z1730.flags b/test/files/pos/z1730.flags
new file mode 100644
index 0000000000..5319681590
--- /dev/null
+++ b/test/files/pos/z1730.flags
@@ -0,0 +1 @@
+-Ycheck:all \ No newline at end of file
diff --git a/test/files/pos/z1730.scala b/test/files/pos/z1730.scala
new file mode 100644
index 0000000000..0c5875a818
--- /dev/null
+++ b/test/files/pos/z1730.scala
@@ -0,0 +1,13 @@
+// /scala/trac/z1730/a.scala
+// Wed May 23 07:41:25 PDT 2012
+
+class X[R] {
+ def xx(value: => R, addTweak: Boolean = true) = 0
+}
+
+class Boo {
+ implicit def toX[R](v: R) : X[R] = null
+ def goo2 {
+ 3.xx(34)
+ }
+}
diff --git a/test/files/run/origins.check b/test/files/run/origins.check
index ffbf1c1f44..b12cb6e38f 100644
--- a/test/files/run/origins.check
+++ b/test/files/run/origins.check
@@ -1,5 +1,5 @@
->> Origins goxbox.Socks.boop logged 65 calls from 3 distinguished sources.
+>> Origins tag 'boop' logged 65 calls from 3 distinguished sources.
50 Test$$anonfun$f3$1.apply(origins.scala:16)
10 Test$$anonfun$f2$1.apply(origins.scala:15)
diff --git a/test/files/run/origins.scala b/test/files/run/origins.scala
index 9dc6071c7b..0ad92297f5 100644
--- a/test/files/run/origins.scala
+++ b/test/files/run/origins.scala
@@ -2,7 +2,7 @@ import scala.reflect.internal.util.Origins
package goxbox {
object Socks {
- val origins = Origins[Socks.type]("boop")
+ val origins = Origins("boop")
def boop(x: Int): Int = origins { 5 }
}
diff --git a/test/pending/neg/t5008.scala b/test/pending/neg/t5008.scala
new file mode 100644
index 0000000000..2b20bcfe12
--- /dev/null
+++ b/test/pending/neg/t5008.scala
@@ -0,0 +1,165 @@
+// These are members of class bar.C, completely unrelated to class foo.A.
+// The types shown below include types defined within foo.A which are:
+//
+// - qualified private
+// - qualified protected
+// - object protected
+//
+// val a : foo.A = { /* compiled code */ }
+// val xprot1 : java.lang.Object with foo.A.FooProt1 = { /* compiled code */ }
+// val xprot2 : java.lang.Object with foo.A.FooProt2 = { /* compiled code */ }
+// val xprot3 : java.lang.Object with foo.A.FooProt3 = { /* compiled code */ }
+// val xprot4 : java.lang.Object with foo.A.FooProt4 = { /* compiled code */ }
+// val xpriv3 : java.lang.Object with foo.A.FooPriv3 = { /* compiled code */ }
+// val xpriv4 : java.lang.Object with foo.A.FooPriv4 = { /* compiled code */ }
+//
+// Indeed it will tell me a type which I cannot access:
+//
+// scala> new bar.C
+// res0: bar.C = bar.C@1339a0dc
+//
+// scala> res0.xpriv3
+// res1: java.lang.Object with res0.a.FooPriv3 = bar.C$$anon$29@39556aec
+//
+// scala> new res0.a.FooPriv3
+// <console>:9: error: trait FooPriv3 in class A cannot be accessed in foo.A
+// new res0.a.FooPriv3
+// ^
+// Looking at how the compiler prints the types of those vals, one
+// develops a suspicion how some of it is being allowed:
+//
+// val xpriv4: C.this.a.FooPriv4
+// val xpriv3: C.this.a.FooPriv3
+// val xprot4: C.this.a.FooProt4
+// val xprot3: C.this.a.FooProt3
+// val xprot2: C.this.a.FooProt2
+// val xprot1: C.this.a.FooProt1
+//
+// That is, "this" is in the prefix somewhere, it's just not a "this"
+// which has any bearing.
+
+package foo {
+ class A {
+ trait Foo
+
+ protected trait FooProt1
+ protected[this] trait FooProt2
+ protected[foo] trait FooProt3
+ protected[A] trait FooProt4
+
+ private trait FooPriv1
+ private[this] trait FooPriv2
+ private[foo] trait FooPriv3
+ private[A] trait FooPriv4
+
+ type BarProt1 = FooProt1
+ type BarProt2 = FooProt2
+ type BarProt3 = FooProt3
+ type BarProt4 = FooProt4
+
+ // type BarPriv1 = FooPriv1
+ // type BarPriv2 = FooPriv2
+ type BarPriv3 = FooPriv3
+ type BarPriv4 = FooPriv4
+
+ def fprot1(x: FooProt1) = x
+ def fprot2(x: FooProt2) = x
+ def fprot3(x: FooProt3) = x
+ def fprot4(x: FooProt4) = x
+
+ // def fpriv1(x: FooPriv1) = x
+ // def fpriv2(x: FooPriv2) = x
+ def fpriv3(x: FooPriv3) = x
+ def fpriv4(x: FooPriv4) = x
+
+ val yprot1 = new FooProt1 { }
+ val yprot2 = new FooProt2 { }
+ val yprot3 = new FooProt3 { }
+ val yprot4 = new FooProt4 { }
+
+ // val ypriv1 = new FooPriv1 { }
+ // val ypriv2 = new FooPriv2 { }
+ val ypriv3 = new FooPriv3 { }
+ val ypriv4 = new FooPriv4 { }
+
+ def fpriv_alt1(x: FooPriv1) = 0 // !!! isn't the private type now in the signature of the (public) method?
+ def fpriv_alt2(x: FooPriv2) = 0 // !!! isn't the private[this] type now in the signature of the (public) method?
+ }
+ // Same package, subclass
+ class B extends A {
+ val xprot1 = new BarProt1 { }
+ val xprot2 = new BarProt2 { }
+ val xprot3 = new BarProt3 { }
+ val xprot4 = new BarProt4 { }
+
+ // val xpriv1 = new BarPriv1 { }
+ // val xpriv2 = new BarPriv2 { }
+ val xpriv3 = new BarPriv3 { }
+ val xpriv4 = new BarPriv4 { }
+
+ override def fprot1(x: BarProt1) = x
+ override def fprot2(x: BarProt2) = x
+ override def fprot3(x: BarProt3) = x
+ override def fprot4(x: BarProt4) = x
+
+ // override def fpriv1(x: BarPriv1) = x
+ // override def fpriv2(x: BarPriv2) = x
+ override def fpriv3(x: BarPriv3) = x
+ override def fpriv4(x: BarPriv4) = x
+ }
+ // Same package, unrelated class
+ class C {
+ val a = new A
+ import a._
+
+ val xprot1 = new BarProt1 { }
+ val xprot2 = new BarProt2 { }
+ val xprot3 = new BarProt3 { }
+ val xprot4 = new BarProt4 { }
+
+ // val xpriv1 = new BarPriv1 { }
+ // val xpriv2 = new BarPriv2 { }
+ val xpriv3 = new BarPriv3 { }
+ val xpriv4 = new BarPriv4 { }
+ }
+}
+
+package bar {
+ // Different package, subclass
+ class B extends foo.A {
+ val xprot1 = new BarProt1 { }
+ val xprot2 = new BarProt2 { }
+ val xprot3 = new BarProt3 { }
+ val xprot4 = new BarProt4 { }
+
+ // val xpriv1 = new BarPriv1 { }
+ // val xpriv2 = new BarPriv2 { }
+ val xpriv3 = new BarPriv3 { }
+ val xpriv4 = new BarPriv4 { }
+
+ override def fprot1(x: BarProt1) = x
+ override def fprot2(x: BarProt2) = x
+ override def fprot3(x: BarProt3) = x
+ override def fprot4(x: BarProt4) = x
+
+ // override def fpriv1(x: BarPriv1) = x
+ // override def fpriv2(x: BarPriv2) = x
+ override def fpriv3(x: BarPriv3) = x
+ override def fpriv4(x: BarPriv4) = x
+ }
+ // Different package, unrelated class
+ class C {
+ val a = new foo.A
+ import a._
+
+ val xprot1 = new BarProt1 { }
+ val xprot2 = new BarProt2 { }
+ val xprot3 = new BarProt3 { }
+ val xprot4 = new BarProt4 { }
+
+ // val xpriv1 = new BarPriv1 { }
+ // val xpriv2 = new BarPriv2 { }
+ val xpriv3 = new BarPriv3 { }
+ val xpriv4 = new BarPriv4 { }
+ }
+}
diff --git a/test/pending/pos/t4649.flags b/test/pending/pos/t4649.flags
new file mode 100644
index 0000000000..e8fb65d50c
--- /dev/null
+++ b/test/pending/pos/t4649.flags
@@ -0,0 +1 @@
+-Xfatal-warnings \ No newline at end of file
diff --git a/test/pending/pos/t4649.scala b/test/pending/pos/t4649.scala
new file mode 100644
index 0000000000..0d6caa8d7a
--- /dev/null
+++ b/test/pending/pos/t4649.scala
@@ -0,0 +1,6 @@
+object Test {
+ // @annotation.tailrec
+ def lazyFilter[E](s: Stream[E], p: E => Boolean): Stream[E] = s match {
+ case h #:: t => if (p(h)) h #:: lazyFilter(t, p) else lazyFilter(t, p)
+ }
+}
diff --git a/test/pending/run/partial-anyref-spec.check b/test/pending/run/partial-anyref-spec.check
new file mode 100644
index 0000000000..26e41933e7
--- /dev/null
+++ b/test/pending/run/partial-anyref-spec.check
@@ -0,0 +1,13 @@
+Fn$mcII$sp
+Fn$mcLI$sp
+Fn$mcLI$sp
+Fn$mcIL$sp
+Fn
+Fn
+Fn$mcIL$sp
+Fn
+Fn
+Fn3
+Fn3$mcLIDF$sp
+Fn3$mcBIDF$sp
+Fn3
diff --git a/test/pending/run/partial-anyref-spec.scala b/test/pending/run/partial-anyref-spec.scala
new file mode 100644
index 0000000000..49ed514f03
--- /dev/null
+++ b/test/pending/run/partial-anyref-spec.scala
@@ -0,0 +1,31 @@
+class Fn[@specialized(Int, AnyRef) -T, @specialized(Int, AnyRef) +R] {
+ override def toString = getClass.getName
+}
+
+class Fn3[
+ @specialized(Int, AnyRef) -T1,
+ @specialized(Double, AnyRef) -T2,
+ @specialized(Float) -T3,
+ @specialized(Byte, AnyRef) +R
+] {
+ override def toString = getClass.getName
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ println(new Fn[Int, Int])
+ println(new Fn[Int, Byte])
+ println(new Fn[Int, AnyRef])
+ println(new Fn[Byte, Int])
+ println(new Fn[Byte, Byte])
+ println(new Fn[Byte, AnyRef])
+ println(new Fn[AnyRef, Int])
+ println(new Fn[AnyRef, Byte])
+ println(new Fn[AnyRef, AnyRef])
+
+ println(new Fn3[Int, Int, Int, Int])
+ println(new Fn3[Int, Double, Float, Int])
+ println(new Fn3[Int, Double, Float, Byte])
+ println(new Fn3[AnyRef, Double, AnyRef, Int])
+ }
+}