@@ -869,6 +869,18 @@ abstract class Erasure extends AddInterfaces
869869 * - Reset all other type attributes to null, thus enforcing a retyping.
870870 */
871871 private val preTransformer = new TypingTransformer (unit) {
872+ // TODO: since the spec defines instanceOf checks in terms of pattern matching,
873+ // this extractor should share code with TypeTestTreeMaker
874+ object SingletonInstanceCheck {
875+ def unapply (pt : Type ): Option [(TermSymbol , Tree )] = pt match {
876+ case SingleType (_, _) | LiteralType (_) | ThisType (_) | SuperType (_, _) =>
877+ val cmpOp = if (pt <:< AnyValTpe ) Any_equals else Object_eq
878+ val cmpArg = gen.mkAttributedQualifier(pt)
879+ Some ((cmpOp, cmpArg))
880+ case _ =>
881+ None
882+ }
883+ }
872884
873885 private def preEraseNormalApply (tree : Apply ) = {
874886 val fn = tree.fun
@@ -881,12 +893,22 @@ abstract class Erasure extends AddInterfaces
881893 def preEraseAsInstanceOf = {
882894 (fn : @ unchecked) match {
883895 case TypeApply (Select (qual, _), List (targ)) =>
884- if (qual.tpe <:< targ.tpe)
885- atPos(tree.pos) { Typed (qual, TypeTree (targ.tpe)) }
886- else if (isNumericValueClass(qual.tpe.typeSymbol) && isNumericValueClass(targ.tpe.typeSymbol))
887- atPos(tree.pos)(numericConversion(qual, targ.tpe.typeSymbol))
888- else
889- tree
896+ targ.tpe match {
897+ case argTp@ SingletonInstanceCheck (cmpOp, cmpArg) =>
898+ atPos(tree.pos) {
899+ gen.evalOnce(qual, currentOwner, currentUnit) { qual =>
900+ If (Apply (Select (qual(), cmpOp), List (cmpArg)),
901+ Typed (qual(), TypeTree (argTp)),
902+ Throw (ClassCastExceptionClass .tpe_* ))
903+ }
904+ }
905+ case argTp if qual.tpe <:< argTp =>
906+ atPos(tree.pos) { Typed (qual, TypeTree (argTp)) }
907+ case argTp if isNumericValueClass(qual.tpe.typeSymbol) && isNumericValueClass(argTp.typeSymbol) =>
908+ atPos(tree.pos)(numericConversion(qual, argTp.typeSymbol))
909+ case _ =>
910+ tree
911+ }
890912 }
891913 // todo: also handle the case where the singleton type is buried in a compound
892914 }
@@ -904,11 +926,8 @@ abstract class Erasure extends AddInterfaces
904926 List (TypeTree (tp) setPos targ.pos)) setPos fn.pos,
905927 List ()) setPos tree.pos
906928 targ.tpe match {
907- case SingleType (_, _) | LiteralType (_) | ThisType (_) | SuperType (_, _) =>
908- val cmpOp = if (targ.tpe <:< AnyValTpe ) Any_equals else Object_eq
909- atPos(tree.pos) {
910- Apply (Select (qual, cmpOp), List (gen.mkAttributedQualifier(targ.tpe)))
911- }
929+ case SingletonInstanceCheck (cmpOp, cmpArg) =>
930+ atPos(tree.pos) { Apply (Select (qual, cmpOp), List (cmpArg)) }
912931 case RefinedType (parents, decls) if (parents.length >= 2 ) =>
913932 gen.evalOnce(qual, currentOwner, unit) { q =>
914933 // Optimization: don't generate isInstanceOf tests if the static type
0 commit comments