summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-01-21 05:18:54 -0800
committerPaul Phillips <paulp@improving.org>2012-01-21 05:18:54 -0800
commite94035c6a6305b4a8c07c690a316008787aca7b1 (patch)
tree2418dc6c905a8072661b57d80d9813a39d2723c9
parent5a711d7a41c6fe68c5b145b0df7c1a589ba6ea73 (diff)
parent2e092d4822d044312317c502badd8ad5c2674b58 (diff)
downloadscala-e94035c6a6305b4a8c07c690a316008787aca7b1.tar.gz
scala-e94035c6a6305b4a8c07c690a316008787aca7b1.tar.bz2
scala-e94035c6a6305b4a8c07c690a316008787aca7b1.zip
Merge remote-tracking branches 'retronym/ticket/5072' and 'odersky/topic/t5120' into develop
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala15
-rw-r--r--src/compiler/scala/tools/nsc/util/Statistics.scala4
-rw-r--r--test/files/pos/t5120.scala26
3 files changed, 43 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 0fbde03e97..216ad6cd4c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2838,9 +2838,22 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
def packSymbols(hidden: List[Symbol], tp: Type): Type =
if (hidden.isEmpty) tp
else existentialTransform(hidden, tp)(existentialAbstraction)
+
+ def isReferencedFrom(ctx: Context, sym: Symbol): Boolean =
+ ctx.owner.isTerm &&
+ (ctx.scope.exists { dcl => dcl.isInitialized && (dcl.info contains sym) }) ||
+ {
+ var ctx1 = ctx.outer
+ while ((ctx1 != NoContext) && (ctx1.scope eq ctx.scope)) ctx1 = ctx1.outer
+ (ctx1 != NoContext) && isReferencedFrom(ctx1, sym)
+ }
def isCapturedExistential(sym: Symbol) =
- sym hasAllFlags (EXISTENTIAL | CAPTURED) // todo refine this
+ (sym hasAllFlags (EXISTENTIAL | CAPTURED)) && {
+ val start = startTimer(isReferencedNanos)
+ try !isReferencedFrom(context, sym)
+ finally stopTimer(isReferencedNanos, start)
+ }
def packCaptured(tpe: Type): Type = {
val captured = mutable.Set[Symbol]()
diff --git a/src/compiler/scala/tools/nsc/util/Statistics.scala b/src/compiler/scala/tools/nsc/util/Statistics.scala
index 27239b9b9f..f7c27dceb5 100644
--- a/src/compiler/scala/tools/nsc/util/Statistics.scala
+++ b/src/compiler/scala/tools/nsc/util/Statistics.scala
@@ -20,7 +20,7 @@ class Statistics extends scala.reflect.internal.util.Statistics {
val typedSelectCount = new Counter
val typerNanos = new Timer
val classReadNanos = new Timer
-
+
val failedApplyNanos = new Timer
val failedOpEqNanos = new Timer
val failedSilentNanos = new Timer
@@ -48,6 +48,7 @@ class Statistics extends scala.reflect.internal.util.Statistics {
val subtypeImprovCount = new SubCounter(subtypeCount)
val subtypeETNanos = new Timer
val matchesPtNanos = new Timer
+ val isReferencedNanos = new Timer
val ctr1 = new Counter
val ctr2 = new Counter
val ctr3 = new Counter
@@ -137,6 +138,7 @@ abstract class StatisticsInfo {
inform("time spent in failed : "+showRelTyper(failedSilentNanos))
inform(" failed apply : "+showRelTyper(failedApplyNanos))
inform(" failed op= : "+showRelTyper(failedOpEqNanos))
+ inform("time spent ref scanning : "+showRelTyper(isReferencedNanos))
inform("micros by tree node : "+showCounts(microsByType))
inform("#visits by tree node : "+showCounts(visitsByType))
val average = new ClassCounts
diff --git a/test/files/pos/t5120.scala b/test/files/pos/t5120.scala
new file mode 100644
index 0000000000..2c193d129d
--- /dev/null
+++ b/test/files/pos/t5120.scala
@@ -0,0 +1,26 @@
+// An example extracted from SBT by Iulian
+// that showed that the previous fix to t5120
+// was too strict.
+class Test {
+ class ScopedKey[T]
+ class Value[T]
+
+ class Compiled[T](val settings: Seq[Pair[T]])
+
+ case class Pair[T](k: ScopedKey[T], v: ScopedKey[T])
+
+ def transform[T](x: T) = x
+
+ def test(compiledSettings: Seq[Compiled[_]]) = {
+ compiledSettings flatMap { cs => // cd: Compiled[_] in both versions
+ (cs.settings map { s => // cs.settings: Seq[Compiled[$1]] in trunk, Seq[Compiled[$1]] forSome $1 in 2.9.1
+ // s: Pair[$1] in trunk, Pair[$1] in 2.9.1
+ val t = transform(s.v) // t: ScopedKey[_] in trunk, ScopedKey[$1] in 2.9.1
+ foo(s.k, t)
+ t
+ }) : Seq[ScopedKey[_]]
+ }
+ }
+
+ def foo[T](x: ScopedKey[T], v: ScopedKey[T]) {}
+}