From 817579904bd225cc8322232f96e6d08e3034366d Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Tue, 22 Nov 2011 23:10:30 +0000 Subject: type test optimization now takes GADT hack into... type test optimization now takes GADT hack into account --- .../scala/tools/nsc/typechecker/PatMatVirtualiser.scala | 10 +++++----- 1 file 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) -- cgit v1.2.3