diff options
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 |