@@ -869,6 +869,18 @@ abstract class Erasure extends AddInterfaces
869
869
* - Reset all other type attributes to null, thus enforcing a retyping.
870
870
*/
871
871
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
+ }
872
884
873
885
private def preEraseNormalApply (tree : Apply ) = {
874
886
val fn = tree.fun
@@ -881,12 +893,22 @@ abstract class Erasure extends AddInterfaces
881
893
def preEraseAsInstanceOf = {
882
894
(fn : @ unchecked) match {
883
895
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) if sip23 => // compiler has an unsound asInstanceOf[global.type]...
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
+ }
890
912
}
891
913
// todo: also handle the case where the singleton type is buried in a compound
892
914
}
@@ -904,11 +926,8 @@ abstract class Erasure extends AddInterfaces
904
926
List (TypeTree (tp) setPos targ.pos)) setPos fn.pos,
905
927
List ()) setPos tree.pos
906
928
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)) }
912
931
case RefinedType (parents, decls) if (parents.length >= 2 ) =>
913
932
gen.evalOnce(qual, currentOwner, unit) { q =>
914
933
// Optimization: don't generate isInstanceOf tests if the static type
0 commit comments