Skip to content

Commit 0e9b1ba

Browse files
committed
Don't warn for erasure on arrays with value types
1 parent 76ea47c commit 0e9b1ba

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

compiler/src/dotty/tools/dotc/transform/IsInstanceOfEvaluator.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,14 @@ class IsInstanceOfEvaluator extends MiniPhaseTransform { thisTransformer =>
129129
val selClassNonFinal = selClass && !(selector.typeSymbol is Final)
130130
val selFinalClass = selClass && (selector.typeSymbol is Final)
131131
val selTypeParam = tree.args.head.tpe.widen match {
132-
case AppliedType(tycon, args) =>
133-
ctx.uncheckedWarning(
132+
case tp @ AppliedType(tycon, args) =>
133+
// If the type is Array[X] where x extends AnyVal, this shouldn't yield a warning:
134+
val illegalComparison = !(tp.isRef(defn.ArrayClass) && {
135+
args.head.derivesFrom(defn.AnyValClass) ||
136+
args.head.isRef(defn.AnyClass)
137+
})
138+
139+
if (illegalComparison) ctx.uncheckedWarning(
134140
ErasedType(hl"""|Since type parameters are erased, you should not match on them in
135141
|${"match"} expressions."""),
136142
tree.pos

tests/repl/erasure.check

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
scala> def unsafeCast[S](a: Any) = a match { case s: S => s; case _ => ??? }
2+
-- [E035] Erased Type Unchecked Warning: <console> -----------------------------
3+
4 |def unsafeCast[S](a: Any) = a match { case s: S => s; case _ => ??? }
4+
| ^
5+
| abstract type pattern is unchecked since it is eliminated by erasure
6+
7+
longer explanation available when compiling with `-explain`
8+
def unsafeCast[S](a: Any): [S] => (a: Any)S
9+
scala> unsafeCast[String](1)
10+
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
11+
at .<init>(<console>:6)
12+
at .<clinit>(<console>)
13+
at RequestResult$.<init>(<console>:3)
14+
at RequestResult$.<clinit>(<console>)
15+
at RequestResult$result(<console>)
16+
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
17+
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.jav...
18+
scala> class A; def unsafeCast2[S <: A](a: Any) = a match { case s: S => s; case _ => ??? }
19+
-- [E035] Erased Type Unchecked Warning: <console> -----------------------------
20+
4 |class A; def unsafeCast2[S <: A](a: Any) = a match { case s: S => s; case _ => ??? }
21+
| ^
22+
| abstract type pattern is unchecked since it is eliminated by erasure
23+
24+
longer explanation available when compiling with `-explain`
25+
defined class A
26+
def unsafeCast2[S <: A](a: Any): [S <: A] => (a: Any)S
27+
scala> def matchArray1[A](xs: Array[A]) = xs match { case xs: Array[Int] => xs; case xs: Array[A] => ??? }
28+
def matchArray1[A](xs: Array[A]): [A] => (xs: Array[A])Array[Int]
29+
scala> def matchArray2[A](xs: Array[Any]) = xs match { case xs: Array[Int] => xs; case xs: Array[A] => ??? }
30+
-- [E035] Erased Type Unchecked Warning: <console> -----------------------------
31+
5 |def matchArray2[A](xs: Array[Any]) = xs match { case xs: Array[Int] => xs; case xs: Array[A] => ??? }
32+
| ^
33+
| abstract type pattern is unchecked since it is eliminated by erasure
34+
35+
longer explanation available when compiling with `-explain`
36+
def matchArray2[A](xs: Array[Any]): [A] => (xs: Array[Any])Array[Int]
37+
scala> def matchArray3[A](xs: Array[A]) = xs match { case xs: Array[Int] => xs; case xs: Array[AnyRef] => ???; case xs: Array[Any] => ??? }
38+
-- [E035] Erased Type Unchecked Warning: <console> -----------------------------
39+
5 |def matchArray3[A](xs: Array[A]) = xs match { case xs: Array[Int] => xs; case xs: Array[AnyRef] => ???; case xs: Array[Any] => ??? }
40+
| ^
41+
| abstract type pattern is unchecked since it is eliminated by erasure
42+
43+
longer explanation available when compiling with `-explain`
44+
def matchArray3[A](xs: Array[A]): [A] => (xs: Array[A])Array[Int]
45+
scala> def matchArray4(xs: Array[Any]) = xs match { case xs: Array[Int] => xs; case xs: Array[A] => ???; case xs: Array[Any] => ??? }
46+
-- [E035] Erased Type Unchecked Warning: <console> -----------------------------
47+
5 |def matchArray4(xs: Array[Any]) = xs match { case xs: Array[Int] => xs; case xs: Array[A] => ???; case xs: Array[Any] => ??? }
48+
| ^
49+
| abstract type pattern is unchecked since it is eliminated by erasure
50+
51+
longer explanation available when compiling with `-explain`
52+
def matchArray4(xs: Array[Any]): Array[Int]
53+
scala> :quit

0 commit comments

Comments
 (0)