From d02d4b86dfe281cca18760d49f026a2a9b332e53 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 25 Sep 2024 16:43:07 +0100 Subject: [PATCH 1/3] Avoid erasure/preErasure issues around Any in transformIsInstanceOf The testType Any is erased to Object, but the expr type Int isn't erased to Integer, so then it fails as Int !<: Object. We avoid the problem by feeding in AnyVal, leading to a (possibly elided) non-null test only. --- .../src/dotty/tools/dotc/transform/TypeTestsCasts.scala | 6 +++++- tests/pos/i21544.scala | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i21544.scala diff --git a/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala b/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala index 082c239c6443..45596e1d47f6 100644 --- a/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala +++ b/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala @@ -358,7 +358,11 @@ object TypeTestsCasts { report.error(em"$untestable cannot be used in runtime type tests", tree.srcPos) constant(expr, Literal(Constant(false))) case _ => - val erasedTestType = erasure(testType) + val erasedTestType = + if testType.isAny && expr.tpe.isPrimitiveValueType then + defn.AnyValType + else + erasure(testType) transformIsInstanceOf(expr, erasedTestType, erasedTestType, flagUnrelated) } diff --git a/tests/pos/i21544.scala b/tests/pos/i21544.scala new file mode 100644 index 000000000000..45da101e7490 --- /dev/null +++ b/tests/pos/i21544.scala @@ -0,0 +1,2 @@ +class Test(): + def m1(xs: List[Boolean]) = for (x: Any) <- xs yield x From 7b721f0fdc032e871737d11ed1841c9fdc4ef98d Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 30 Oct 2024 14:04:44 +0000 Subject: [PATCH 2/3] Simplify transformIsInstanceOf check --- .../src/dotty/tools/dotc/transform/TypeTestsCasts.scala | 9 +++------ tests/pos/i21544.scala | 2 ++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala b/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala index 45596e1d47f6..c1dd6bc6509e 100644 --- a/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala +++ b/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala @@ -256,7 +256,8 @@ object TypeTestsCasts { else foundClasses.exists(check) end checkSensical - if (expr.tpe <:< testType) && inMatch then + val tp = if expr.tpe.isPrimitiveValueType then defn.boxedType(expr.tpe) else expr.tpe + if tp <:< testType && inMatch then if expr.tpe.isNotNull then constant(expr, Literal(Constant(true))) else expr.testNotNull else { @@ -358,11 +359,7 @@ object TypeTestsCasts { report.error(em"$untestable cannot be used in runtime type tests", tree.srcPos) constant(expr, Literal(Constant(false))) case _ => - val erasedTestType = - if testType.isAny && expr.tpe.isPrimitiveValueType then - defn.AnyValType - else - erasure(testType) + val erasedTestType = erasure(testType) transformIsInstanceOf(expr, erasedTestType, erasedTestType, flagUnrelated) } diff --git a/tests/pos/i21544.scala b/tests/pos/i21544.scala index 45da101e7490..08a3911e4412 100644 --- a/tests/pos/i21544.scala +++ b/tests/pos/i21544.scala @@ -1,2 +1,4 @@ class Test(): def m1(xs: List[Boolean]) = for (x: Any) <- xs yield x + def m2(xs: List[Boolean]) = for (x: AnyVal) <- xs yield x + def m3(xs: List[Boolean]) = for (x: Matchable) <- xs yield x From 49d876a87851b78a63f3027811b41791a2fe583c Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sat, 2 Nov 2024 18:09:27 +0000 Subject: [PATCH 3/3] Add extra isInstanceOf test cases --- tests/pos/i21544.scala | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/pos/i21544.scala b/tests/pos/i21544.scala index 08a3911e4412..b2d978ea7d02 100644 --- a/tests/pos/i21544.scala +++ b/tests/pos/i21544.scala @@ -2,3 +2,12 @@ class Test(): def m1(xs: List[Boolean]) = for (x: Any) <- xs yield x def m2(xs: List[Boolean]) = for (x: AnyVal) <- xs yield x def m3(xs: List[Boolean]) = for (x: Matchable) <- xs yield x + + def v1(xs: List[AnyVal]) = for (x: Any) <- xs yield x + def v2(xs: List[AnyVal]) = for (x: AnyVal) <- xs yield x + def v3(xs: List[AnyVal]) = for (x: Matchable) <- xs yield x + + def t1(xs: List[Matchable]) = for (x: Any) <- xs yield x + def t2(xs: List[Matchable]) = for (x: Matchable) <- xs yield x + + def a1(xs: List[Any]) = for (x: Any) <- xs yield x