Skip to content

Commit 1a8af58

Browse files
committed
Relax warnings when matching from Seq to List
1 parent 1f1b1ba commit 1a8af58

File tree

3 files changed

+28
-5
lines changed

3 files changed

+28
-5
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,9 @@ class Definitions {
357357
List(AnyClass.typeRef), EmptyScope)
358358
def SingletonType = SingletonClass.typeRef
359359

360+
lazy val ListType: TypeRef = ctx.requiredClassRef("scala.collection.immutable.List")
361+
def ListClass(implicit ctx: Context) = ListType.symbol.asClass
362+
360363
lazy val SeqType: TypeRef = ctx.requiredClassRef("scala.collection.Seq")
361364
def SeqClass(implicit ctx: Context) = SeqType.symbol.asClass
362365

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

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,27 @@ class IsInstanceOfEvaluator extends MiniPhaseTransform { thisTransformer =>
146146
// has @unchecked annotation to suppress warnings
147147
val hasUncheckedAnnot = arg.hasAnnotation(defn.UncheckedAnnot)
148148

149-
if (!topType && !hasUncheckedAnnot && !anyValArray) ctx.uncheckedWarning(
150-
ErasedType(hl"""|Since type parameters are erased, you should not match on them in
151-
|${"match"} expressions."""),
152-
tree.pos
153-
)
149+
// we don't want to warn when matching on `List` from `Seq` e.g:
150+
// (xs: Seq[Int]) match { case xs: List[Int] => ??? }
151+
val matchingSeqToList = {
152+
val hasSameTypeArgs = s.qualifier.tpe.widen match {
153+
case AppliedType(_, scrutArg :: Nil) =>
154+
(scrutArg eq arg) || arg <:< scrutArg
155+
case _ => false
156+
}
157+
158+
scrutinee.isRef(defn.SeqClass) &&
159+
tp.isRef(defn.ListClass) &&
160+
hasSameTypeArgs
161+
}
162+
163+
if (!topType && !hasUncheckedAnnot && !matchingSeqToList && !anyValArray) {
164+
ctx.uncheckedWarning(
165+
ErasedType(hl"""|Since type parameters are erased, you should not match on them in
166+
|${"match"} expressions."""),
167+
tree.pos
168+
)
169+
}
154170
true
155171
case _ =>
156172
if (tree.args.head.symbol.is(TypeParam)) {

tests/repl/erasure.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,8 @@ scala> def matchList2(xs: List[Any]) = xs match { case List() => ???; case _ =>
5252
def matchList2(xs: List[Any]): Nothing
5353
scala> def matchList3(xs: Seq[_]) = xs match { case List() => ???; case _ => ??? }
5454
def matchList3(xs: Seq[_]): Nothing
55+
scala> val xs: Seq[Int] = Seq(1,2,3)
56+
val xs: scala.collection.Seq[Int] = List(1, 2, 3)
57+
scala> val xsMatch = xs match { case ss: List[Int] => 1 }
58+
val xsMatch: Int = 1
5559
scala> :quit

0 commit comments

Comments
 (0)