diff --git a/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala b/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala index 0b880afdd995..7d1740b2b581 100644 --- a/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala +++ b/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala @@ -243,7 +243,23 @@ object TypeTestsCasts { else foundClasses.exists(check) end checkSensical - if (expr.tpe <:< testType) + def hasUncheckedPrefix(tpe: Type): Boolean = tpe.stripped match + case tpe: TermRef => + tpe.symbol.info.hasAnnotation(defn.UncheckedAnnot) + || hasUncheckedPrefix(tpe.prefix) + case tpe: TypeRef => + tpe.symbol.hasAnnotation(defn.UncheckedAnnot) + || hasUncheckedPrefix(tpe.prefix) + case tpe: AndOrType => + hasUncheckedPrefix(tpe.tp1) || hasUncheckedPrefix(tpe.tp2) + case tpe: AppliedType => + hasUncheckedPrefix(tpe.tycon) || tpe.args.exists(hasUncheckedPrefix) + case tpe: TypeProxy => + hasUncheckedPrefix(tpe.underlying) + case _ => + false + + if expr.tpe <:< testType && !hasUncheckedPrefix(expr.tpe) then if (expr.tpe.isNotNull) { if (!inMatch) report.warning(TypeTestAlwaysSucceeds(expr.tpe, testType), tree.srcPos) constant(expr, Literal(Constant(true))) diff --git a/tests/neg/tuplePatDef.scala b/tests/neg/tuplePatDef.scala new file mode 100644 index 000000000000..03aa4bcd15e7 --- /dev/null +++ b/tests/neg/tuplePatDef.scala @@ -0,0 +1,4 @@ + +object Test { + val (x,y): (String, Int) = null // error: unreachable +} diff --git a/tests/pos/t2613.scala b/tests/pos/t2613.scala index 17ebe2d7e9bf..2540ef12df7b 100644 --- a/tests/pos/t2613.scala +++ b/tests/pos/t2613.scala @@ -7,5 +7,5 @@ object Test { type M = MyRelation[_ <: Row, _ <: MyRelation[_, _]] - val (x,y): (String, M) = null + val (x,y): (String, M) = null : Any } diff --git a/tests/pos/tuplePatDef.scala b/tests/pos/tuplePatDef.scala deleted file mode 100644 index 22f8f8e7d6ed..000000000000 --- a/tests/pos/tuplePatDef.scala +++ /dev/null @@ -1,4 +0,0 @@ - -object Test { - val (x,y): (String, Int) = null -} diff --git a/tests/run/i14705.scala b/tests/run/i14705.scala new file mode 100644 index 000000000000..1ee4f6c7752b --- /dev/null +++ b/tests/run/i14705.scala @@ -0,0 +1,19 @@ +trait Fruit +case class Apple() extends Fruit +case class Orange() extends Fruit + +case class Box[C](fruit: C) extends Fruit + +val apple = Box(fruit = Apple()) +val orange = Box(fruit = Orange()) + + +val result = List(apple, orange).map { + case appleBox: Box[Apple] @unchecked if appleBox.fruit.isInstanceOf[Apple] => //contains apple + "apple" + case _ => + "orange" +} + +@main def Test = + assert(result == List("apple", "orange"))