diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2012-03-17 12:15:37 +0100 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2012-03-20 19:54:08 +0100 |
commit | 9e513a6d29f2cb060caf58ff5568d7955b96305a (patch) | |
tree | 2ae9ab7e38b0fa09aa93ebb18b277260db88a150 /src | |
parent | b046a6e3316df8b27ac31e71da1a139c800ccce7 (diff) | |
download | scala-9e513a6d29f2cb060caf58ff5568d7955b96305a.tar.gz scala-9e513a6d29f2cb060caf58ff5568d7955b96305a.tar.bz2 scala-9e513a6d29f2cb060caf58ff5568d7955b96305a.zip |
[vpm] fix half of my existential troubles
no need for the clunky repackExistential
pack the type of each case instead, since the skolems we've created shouldn't last beyond the case anyway
this way we don't end up with fresh, incompatible, skolems for every case, but a neatly packed existential
Diffstat (limited to 'src')
3 files changed, 10 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)) |