summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2011-11-01 17:16:51 +0000
committerMartin Odersky <odersky@gmail.com>2011-11-01 17:16:51 +0000
commitb7b81ca286b1f426cd19befd50fbc513bb82282f (patch)
tree1008c7594c42995b7758b2bb09f87134ac98b2d1 /src
parent69b3cd50923b3f495f1e421e8a4ac505044f3c40 (diff)
downloadscala-b7b81ca286b1f426cd19befd50fbc513bb82282f.tar.gz
scala-b7b81ca286b1f426cd19befd50fbc513bb82282f.tar.bz2
scala-b7b81ca286b1f426cd19befd50fbc513bb82282f.zip
Fixed type unsoundness problem in t5120 and als...
Fixed type unsoundness problem in t5120 and also discovered by roman.kalukiewicz@gmail.com. Fix should be refined further, as I am not convinced we are quite done yet. Review by moors.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala15
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
2 files changed, 13 insertions, 4 deletions
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index bc739e58a9..c542c818c1 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -560,11 +560,19 @@ trait Types extends api.Types { self: SymbolTable =>
def asSeenFrom(pre: Type, clazz: Symbol): Type =
if (isTrivial || phase.erasedTypes && pre.typeSymbol != ArrayClass) this
else {
+// scala.tools.nsc.util.trace.when(pre.isInstanceOf[ExistentialType])("X "+this+".asSeenfrom("+pre+","+clazz+" = ") {
incCounter(asSeenFromCount)
val start = startTimer(asSeenFromNanos)
val m = new AsSeenFromMap(pre.normalize, clazz)
val tp = m apply this
- val result = existentialAbstraction(m.capturedParams, tp)
+ val tp1 = existentialAbstraction(m.capturedParams, tp)
+ val result: Type =
+ if (m.capturedSkolems.isEmpty) tp1
+ else {
+ val captured = cloneSymbols(m.capturedSkolems)
+ captured foreach (_ setFlag CAPTURED)
+ tp1.substSym(m.capturedSkolems, captured)
+ }
stopTimer(asSeenFromNanos, start)
result
}
@@ -3606,6 +3614,7 @@ A type's typeSymbol should never be inspected directly.
/** A map to compute the asSeenFrom method */
class AsSeenFromMap(pre: Type, clazz: Symbol) extends TypeMap with KeepOnlyTypeConstraints {
+ var capturedSkolems: List[Symbol] = List()
var capturedParams: List[Symbol] = List()
override def mapOver(tree: Tree, giveup: ()=>Nothing): Tree = {
@@ -3679,7 +3688,7 @@ A type's typeSymbol should never be inspected directly.
pre1
}
} else {
- toPrefix(base(pre, clazz).prefix, clazz.owner);
+ toPrefix(base(pre, clazz).prefix, clazz.owner)
}
toPrefix(pre, clazz)
case SingleType(pre, sym) =>
@@ -3752,7 +3761,7 @@ A type's typeSymbol should never be inspected directly.
" gets applied to arguments "+baseargs.mkString("[",",","]")+", phase = "+phase)
}
case ExistentialType(tparams, qtpe) =>
- capturedParams = capturedParams union tparams
+ capturedSkolems = capturedSkolems union tparams
toInstance(qtpe, clazz)
case t =>
throwError
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 976fcc8f7c..32ea3eb3b3 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2841,7 +2841,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
def isLocal(sym: Symbol): Boolean =
if (sym == NoSymbol || sym.isRefinementClass || sym.isLocalDummy) false
else if (owner == NoSymbol) tree exists (defines(_, sym))
- else containsDef(owner, sym) || isRawParameter(sym)
+ else containsDef(owner, sym) || isRawParameter(sym) || ((sym hasFlag EXISTENTIAL) && (sym hasFlag CAPTURED)) // todo refine this
def containsLocal(tp: Type): Boolean =
tp exists (t => isLocal(t.typeSymbol) || isLocal(t.termSymbol))
val normalizeLocals = new TypeMap {