summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala10
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala6
-rw-r--r--test/files/pos/virtpatmat_exist4.scala35
4 files changed, 45 insertions, 15 deletions
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index 549c9e4607..2bb19e2b65 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -2617,15 +2617,6 @@ trait Types extends api.Types { self: SymbolTable =>
}
}
- // TODO: I don't really know why this happens -- maybe because
- // the owner hierarchy changes? the other workaround (besides
- // repackExistential) is to explicitly pass expectedTp as the type
- // argument for the call to guard, but repacking the existential
- // somehow feels more robust
- //
- // TODO: check if optimization makes a difference, try something else
- // if necessary (cache?)
-
/** Repack existential types, otherwise they sometimes get unpacked in the
* wrong location (type inference comes up with an unexpected skolem)
*/
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
index 34fefd20fe..de7f03dc62 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
@@ -1037,7 +1037,7 @@ class Foo(x: Other) { x._1 } // no error in this order
// assert(owner ne null); assert(owner ne NoSymbol)
def freshSym(pos: Position, tp: Type = NoType, prefix: String = "x") =
- NoSymbol.newTermSymbol(freshName(prefix), pos) setInfo repackExistential(tp)
+ NoSymbol.newTermSymbol(freshName(prefix), pos) setInfo /*repackExistential*/(tp)
// codegen relevant to the structure of the translation (how extractors are combined)
trait AbsCodegen {
@@ -1079,18 +1079,18 @@ class Foo(x: Other) { x._1 } // no error in this order
def and(a: Tree, b: Tree): Tree = a AND b
// the force is needed mainly to deal with the GADT typing hack (we can't detect it otherwise as tp nor pt need contain an abstract type, we're just casting wildly)
- def _asInstanceOf(t: Tree, tp: Type, force: Boolean = false): Tree = { val tpX = repackExistential(tp)
+ def _asInstanceOf(t: Tree, tp: Type, force: Boolean = false): Tree = { val tpX = /*repackExistential*/(tp)
if (!force && (t.tpe ne NoType) && t.isTyped && typesConform(t.tpe, tpX)) t //{ println("warning: emitted redundant asInstanceOf: "+(t, t.tpe, tp)); t } //.setType(tpX)
else gen.mkAsInstanceOf(t, tpX, true, false)
}
- def _isInstanceOf(b: Symbol, tp: Type): Tree = gen.mkIsInstanceOf(REF(b), repackExistential(tp), true, false)
- // { val tpX = repackExistential(tp)
+ def _isInstanceOf(b: Symbol, tp: Type): Tree = gen.mkIsInstanceOf(REF(b), /*repackExistential*/(tp), true, false)
+ // { val tpX = /*repackExistential*/(tp)
// if (typesConform(b.info, tpX)) { println("warning: emitted spurious isInstanceOf: "+(b, tp)); TRUE }
// else gen.mkIsInstanceOf(REF(b), tpX, true, false)
// }
- def _asInstanceOf(b: Symbol, tp: Type): Tree = { val tpX = repackExistential(tp)
+ def _asInstanceOf(b: Symbol, tp: Type): Tree = { val tpX = /*repackExistential*/(tp)
if (typesConform(b.info, tpX)) REF(b) //{ println("warning: emitted redundant asInstanceOf: "+(b, b.info, tp)); REF(b) } //.setType(tpX)
else gen.mkAsInstanceOf(REF(b), tpX, true, false)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 506e347828..daf4ddd100 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2140,7 +2140,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
def typedCases(cases: List[CaseDef], pattp: Type, pt: Type): List[CaseDef] =
cases mapConserve { cdef =>
- newTyper(context.makeNewScope(cdef, context.owner)).typedCase(cdef, pattp, pt)
+ val caseTyped = newTyper(context.makeNewScope(cdef, context.owner)).typedCase(cdef, pattp, pt)
+ if (opt.virtPatmat) {
+ val tpPacked = packedType(caseTyped, context.owner)
+ caseTyped setType tpPacked
+ } else caseTyped
}
def adaptCase(cdef: CaseDef, mode: Int, tpe: Type): CaseDef = deriveCaseDef(cdef)(adapt(_, mode, tpe))
diff --git a/test/files/pos/virtpatmat_exist4.scala b/test/files/pos/virtpatmat_exist4.scala
new file mode 100644
index 0000000000..a04d0e3229
--- /dev/null
+++ b/test/files/pos/virtpatmat_exist4.scala
@@ -0,0 +1,35 @@
+trait Global {
+ trait Tree
+ trait Symbol { def foo: Boolean }
+}
+
+trait IMain { self: MemberHandlers =>
+ val global: Global
+ def handlers: List[MemberHandler]
+}
+
+trait MemberHandlers {
+ val intp: IMain
+ import intp.global._
+ sealed abstract class MemberHandler(val member: Tree) {
+ def importedSymbols: List[Symbol]
+ }
+}
+
+object Test {
+ var intp: IMain with MemberHandlers = null
+
+ val handlers = intp.handlers
+ handlers.filterNot(_.importedSymbols.isEmpty).zipWithIndex foreach {
+ case (handler, idx) =>
+ val (types, terms) = handler.importedSymbols partition (_.foo)
+ }
+}
+
+object Test2 {
+ type JClass = java.lang.Class[_]
+
+ def tvarString(bounds: List[AnyRef]) = {
+ bounds collect { case x: JClass => x }
+ }
+} \ No newline at end of file