aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
authorodersky <odersky@gmail.com>2016-07-27 15:45:21 +0200
committerGitHub <noreply@github.com>2016-07-27 15:45:21 +0200
commit5ffce6e910f4cc1fced15824df86a9524be81681 (patch)
tree09b9ed81fe4457338db10982a47a62936fb2eca7 /src/dotty/tools/dotc
parentfec3ec3e1f5b8c1ed9af3c51010832f99d958b23 (diff)
parent25421111a730681504c73b978e454dfa7a6ff447 (diff)
downloaddotty-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/dotty/tools/dotc')
-rw-r--r--src/dotty/tools/dotc/transform/TypeTestsCasts.scala31
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 _ =>