summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2011-11-22 23:10:30 +0000
committerAdriaan Moors <adriaan.moors@epfl.ch>2011-11-22 23:10:30 +0000
commit817579904bd225cc8322232f96e6d08e3034366d (patch)
treef10ff2274ac472b72950ccb302ae4a3fe0d26cc1
parent4fca89bfd0a6a27a3aed03daad96bfc55eb88f09 (diff)
downloadscala-817579904bd225cc8322232f96e6d08e3034366d.tar.gz
scala-817579904bd225cc8322232f96e6d08e3034366d.tar.bz2
scala-817579904bd225cc8322232f96e6d08e3034366d.zip
type test optimization now takes GADT hack into...
type test optimization now takes GADT hack into account
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala10
1 files changed, 5 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
index 49f3330297..76d3a58597 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
@@ -881,8 +881,7 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
import CODE._
- // cf. !needsTypeTest from above
- def typesConform(tp: Type, pt: Type) = (tp eq pt) || (tp <:< pt)
+ def typesConform(tp: Type, pt: Type) = ((tp eq pt) || (tp <:< pt))
trait CommonCodeGen extends AbsCodeGen { self: CommonCodeGen with MatchingStrategyGen with MonadInstGen =>
def fun(arg: Symbol, body: Tree): Tree = Function(List(ValDef(arg)), body)
@@ -892,8 +891,9 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
def _equals(checker: Tree, binder: Symbol): Tree = checker MEMBER_== REF(binder) // NOTE: checker must be the target of the ==, that's the patmat semantics for ya
def and(a: Tree, b: Tree): Tree = a AND b
- def _asInstanceOf(t: Tree, tp: Type): Tree = { val tpX = repackExistential(tp)
- if ((t.tpe ne NoType) && t.isTyped && typesConform(t.tpe, tpX)) t //{ println("warning: emitted redundant asInstanceOf: "+(t, t.tpe, tp)); t } //.setType(tpX)
+ // 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)
+ 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)
}
@@ -917,7 +917,7 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
def or(f: Tree, as: List[Tree]): Tree = (matchingStrategy DOT vpmName.or)((f :: as): _*) // matchingStrategy.or(f, as)
def guard(c: Tree): Tree = (matchingStrategy DOT vpmName.guard)(c, UNIT) // matchingStrategy.guard(c, then) -- a user-defined guard
// TODO: get rid of the cast when it's unnecessary, but this requires type checking `body` -- maybe this should be one of the optimisations we perform after generating the tree
- def caseResult(res: Tree, tp: Type): Tree = (matchingStrategy DOT vpmName.caseResult) (_asInstanceOf(res, tp)) // matchingStrategy.caseResult(res), like one, but blow this one away for isDefinedAt (since it's the RHS of a case)
+ def caseResult(res: Tree, tp: Type): Tree = (matchingStrategy DOT vpmName.caseResult) (_asInstanceOf(res, tp, force = true)) // matchingStrategy.caseResult(res), like one, but blow this one away for isDefinedAt (since it's the RHS of a case)
// an internal guard TODO: use different method call so exhaustiveness can distinguish it from user-defined guards
def cond(c: Tree, then: Tree = UNIT, tp: Type = NoType): Tree = genTypeApply((matchingStrategy DOT vpmName.guard), repackExistential(tp)) APPLY (c, then) // matchingStrategy.guard(c, then)