diff options
author | odersky <odersky@gmail.com> | 2016-07-27 15:45:21 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-07-27 15:45:21 +0200 |
commit | 5ffce6e910f4cc1fced15824df86a9524be81681 (patch) | |
tree | 09b9ed81fe4457338db10982a47a62936fb2eca7 /src | |
parent | fec3ec3e1f5b8c1ed9af3c51010832f99d958b23 (diff) | |
parent | 25421111a730681504c73b978e454dfa7a6ff447 (diff) | |
download | dotty-5ffce6e910f4cc1fced15824df86a9524be81681.tar.gz dotty-5ffce6e910f4cc1fced15824df86a9524be81681.tar.bz2 dotty-5ffce6e910f4cc1fced15824df86a9524be81681.zip |
Merge pull request #1415 from dotty-staging/fix-i1354
fix #1354: improve type test of union types
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/transform/TypeTestsCasts.scala | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/transform/TypeTestsCasts.scala b/src/dotty/tools/dotc/transform/TypeTestsCasts.scala index c57d6fd1a..6de2bf44c 100644 --- a/src/dotty/tools/dotc/transform/TypeTestsCasts.scala +++ b/src/dotty/tools/dotc/transform/TypeTestsCasts.scala @@ -1,16 +1,12 @@ package dotty.tools.dotc package transform -import TreeTransforms._ -import core.Denotations._ -import core.SymDenotations._ import core.Contexts._ import core.Symbols._ import core.Types._ import core.Constants._ import core.StdNames._ import core.TypeErasure.isUnboundedGeneric -import typer.ErrorReporting._ import ast.Trees._ import Erasure.Boxing._ import core.TypeErasure._ @@ -92,14 +88,33 @@ trait TypeTestsCasts { unbox(qual.ensureConforms(defn.ObjectType), argType) else if (isDerivedValueClass(argCls)) { qual // adaptToType in Erasure will do the necessary type adaptation - } else + } + else derivedTree(qual, defn.Any_asInstanceOf, argType) } - def erasedArg = erasure(tree.args.head.tpe) + + /** Transform isInstanceOf OrType + * + * expr.isInstanceOf[A | B] ~~> expr.isInstanceOf[A] | expr.isInstanceOf[B] + * + * The transform happens before erasure of `argType`, thus cannot be merged + * with `transformIsInstanceOf`, which depends on erased type of `argType`. + */ + def transformOrTypeTest(qual: Tree, argType: Type): Tree = argType match { + case OrType(tp1, tp2) => + evalOnce(qual) { fun => + transformOrTypeTest(fun, tp1) + .select(nme.OR) + .appliedTo(transformOrTypeTest(fun, tp2)) + } + case _ => + transformIsInstanceOf(qual, erasure(argType)) + } + if (sym eq defn.Any_isInstanceOf) - transformIsInstanceOf(qual, erasedArg) + transformOrTypeTest(qual, tree.args.head.tpe) else if (sym eq defn.Any_asInstanceOf) - transformAsInstanceOf(erasedArg) + transformAsInstanceOf(erasure(tree.args.head.tpe)) else tree case _ => |