type test optimization now takes GADT hack into account

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@26054 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
moors 2011-11-22 23:10:30 +00:00
parent 10314b0cb4
commit e6c345a323
1 changed files with 5 additions and 5 deletions

View File

@ -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)