aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform/TypeTestsCasts.scala
diff options
context:
space:
mode:
authorliu fengyun <liufengyunchina@gmail.com>2016-07-26 10:20:34 +0200
committerliu fengyun <liufengyunchina@gmail.com>2016-07-26 14:37:31 +0200
commit25421111a730681504c73b978e454dfa7a6ff447 (patch)
treee722a7cdc524c0eeacf76b4d6f627406ef4d5c0c /src/dotty/tools/dotc/transform/TypeTestsCasts.scala
parentb6882d6402bfc290a1fe589425d6dc4ff16976a8 (diff)
downloaddotty-25421111a730681504c73b978e454dfa7a6ff447.tar.gz
dotty-25421111a730681504c73b978e454dfa7a6ff447.tar.bz2
dotty-25421111a730681504c73b978e454dfa7a6ff447.zip
fix #1354: improve type test and typecast of union types
Diffstat (limited to 'src/dotty/tools/dotc/transform/TypeTestsCasts.scala')
-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 _ =>