Skip to content

Commit

Permalink
Fix matching on top types
Browse files Browse the repository at this point in the history
  • Loading branch information
felixmulder committed Dec 23, 2016
1 parent 2909603 commit 6974d2a
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,14 @@ class IsInstanceOfEvaluator extends MiniPhaseTransform { thisTransformer =>
/** Check if the selector's potential type parameters will be erased, and if so warn */
val selTypeParam = tree.args.head.tpe.widen match {
case tp @ AppliedType(_, arg :: _) =>
// If the type is `Array[X]` where `X` extends AnyVal or `X =:=
// Any`, this shouldn't yield a warning:
val isArray = tp.isRef(defn.ArrayClass)
val unerased = arg.derivesFrom(defn.AnyValClass) || arg.isRef(defn.AnyClass)
val hasAnnot = arg.hasAnnotation(defn.UncheckedAnnot)

if (!hasAnnot && !(isArray && unerased)) ctx.uncheckedWarning(
// If the type is `Array[X]` where `X` extends AnyVal
val anyValArray = tp.isRef(defn.ArrayClass) && arg.derivesFrom(defn.AnyValClass)
// param is: Any | AnyRef | java.lang.Object
val topType = defn.ObjectType <:< arg
// has @unchecked annotation to suppress warnings
val hasUncheckedAnnot = arg.hasAnnotation(defn.UncheckedAnnot)

if (!topType && !hasUncheckedAnnot && !anyValArray) ctx.uncheckedWarning(
ErasedType(hl"""|Since type parameters are erased, you should not match on them in
|${"match"} expressions."""),
tree.pos
Expand Down
8 changes: 2 additions & 6 deletions tests/repl/erasure.check
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,6 @@ scala> def matchArray2[A](xs: Array[Any]) = xs match { case xs: Array[Int] => xs
longer explanation available when compiling with `-explain`
def matchArray2[A](xs: Array[Any]): [A] => (xs: Array[Any])Array[Int]
scala> def matchArray3[A](xs: Array[A]) = xs match { case xs: Array[Int] => xs; case xs: Array[AnyRef] => ???; case xs: Array[Any] => ??? }
-- [E035] Erased Type Unchecked Warning: <console> -----------------------------
5 |def matchArray3[A](xs: Array[A]) = xs match { case xs: Array[Int] => xs; case xs: Array[AnyRef] => ???; case xs: Array[Any] => ??? }
| ^
| abstract type pattern is unchecked since it is eliminated by erasure

longer explanation available when compiling with `-explain`
def matchArray3[A](xs: Array[A]): [A] => (xs: Array[A])Array[Int]
scala> def matchArray4(xs: Array[Any]) = xs match { case xs: Array[Int] => xs; case xs: Array[A] => ???; case xs: Array[Any] => ??? }
-- [E035] Erased Type Unchecked Warning: <console> -----------------------------
Expand All @@ -56,4 +50,6 @@ scala> def matchList1(xs: List[Any]) = xs match { case xs: List[Int @unchecked]
def matchList1(xs: List[Any]): Nothing
scala> def matchList2(xs: List[Any]) = xs match { case List() => ???; case _ => ??? }
def matchList2(xs: List[Any]): Nothing
scala> def matchList3(xs: Seq[_]) = xs match { case List() => ???; case _ => ??? }
def matchList3(xs: Seq[_]): Nothing
scala> :quit

0 comments on commit 6974d2a

Please sign in to comment.