Skip to content

Commit

Permalink
Unsuppress unchecked warnings
Browse files Browse the repository at this point in the history
And check it with a pos checkfile.
  • Loading branch information
dwijnand committed Sep 4, 2023
1 parent 4740017 commit 9045834
Show file tree
Hide file tree
Showing 15 changed files with 148 additions and 65 deletions.
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/reporting/Message.scala
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ abstract class Message(val errorId: ErrorMessageID)(using Context) { self =>
override def canExplain = true

/** Override with `true` for messages that should always be shown even if their
* position overlaps another messsage of a different class. On the other hand
* position overlaps another message of a different class. On the other hand
* multiple messages of the same class with overlapping positions will lead
* to only a single message of that class to be issued.
*/
Expand Down
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/reporting/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,7 @@ extends Message(PatternMatchExhaustivityID) {

class UncheckedTypePattern(argType: Type, whyNot: String)(using Context)
extends PatternMatchMsg(UncheckedTypePatternID) {
override def showAlways = true
def msg(using Context) = i"the type test for $argType cannot be checked at runtime because $whyNot"
def explain(using Context) =
i"""|Type arguments and type refinements are erased during compile time, thus it's
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ object TypeTestsCasts {
}.apply(tp)

/** Returns true if the type arguments of `P` can be determined from `X` */
def typeArgsTrivial(X: Type, P: AppliedType)(using Context) = inContext(ctx.fresh.setExploreTyperState().setFreshGADTBounds) {
def typeArgsDeterminable(X: Type, P: AppliedType)(using Context) = inContext(ctx.fresh.setExploreTyperState().setFreshGADTBounds) {
val AppliedType(tycon, _) = P

def underlyingLambda(tp: Type): TypeLambda = tp.ensureLambdaSub match {
Expand Down Expand Up @@ -155,7 +155,7 @@ object TypeTestsCasts {
case x =>
// always false test warnings are emitted elsewhere
TypeComparer.provablyDisjoint(x, tpe.derivedAppliedType(tycon, targs.map(_ => WildcardType)))
|| typeArgsTrivial(X, tpe)
|| typeArgsDeterminable(X, tpe)
||| i"its type arguments can't be determined from $X"
}
case AndType(tp1, tp2) => recur(X, tp1) && recur(X, tp2)
Expand Down
16 changes: 9 additions & 7 deletions compiler/src/dotty/tools/dotc/transform/patmat/Space.scala
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ object SpaceEngine {
project(pat)

case Typed(_, tpt) =>
Typ(erase(tpt.tpe.stripAnnots, isValue = true), decomposed = false)
Typ(erase(tpt.tpe.stripAnnots, isValue = true, isTyped = true), decomposed = false)

case This(_) =>
Typ(pat.tpe.stripAnnots, decomposed = false)
Expand Down Expand Up @@ -453,24 +453,26 @@ object SpaceEngine {
* If `isValue` is true, then pattern-bound symbols are erased to its upper bound.
* This is needed to avoid spurious unreachable warnings. See tests/patmat/i6197.scala.
*/
private def erase(tp: Type, inArray: Boolean = false, isValue: Boolean = false)(using Context): Type =
trace(i"erase($tp${if inArray then " inArray" else ""}${if isValue then " isValue" else ""})", debug)(tp match {
private def erase(tp: Type, inArray: Boolean = false, isValue: Boolean = false, isTyped: Boolean = false)(using Context): Type =
trace(i"erase($tp${if inArray then " inArray" else ""}${if isValue then " isValue" else ""}${if isTyped then " isTyped" else ""})", debug)(tp match {
case tp @ AppliedType(tycon, args) if tycon.typeSymbol.isPatternBound =>
WildcardType

case tp @ AppliedType(tycon, args) =>
val inArray = tycon.isRef(defn.ArrayClass)
val args2 = args.map(arg => erase(arg, inArray = inArray, isValue = false))
val args2 =
if isTyped && !inArray then args.map(_ => WildcardType)
else args.map(arg => erase(arg, inArray = inArray, isValue = false))
tp.derivedAppliedType(erase(tycon, inArray, isValue = false), args2)

case tp @ OrType(tp1, tp2) =>
OrType(erase(tp1, inArray, isValue), erase(tp2, inArray, isValue), tp.isSoft)
OrType(erase(tp1, inArray, isValue, isTyped), erase(tp2, inArray, isValue, isTyped), tp.isSoft)

case AndType(tp1, tp2) =>
AndType(erase(tp1, inArray, isValue), erase(tp2, inArray, isValue))
AndType(erase(tp1, inArray, isValue, isTyped), erase(tp2, inArray, isValue, isTyped))

case tp @ RefinedType(parent, _, _) =>
erase(parent, inArray, isValue)
erase(parent, inArray, isValue, isTyped)

case tref: TypeRef if tref.symbol.isPatternBound =>
if inArray then tref.underlying
Expand Down
12 changes: 0 additions & 12 deletions tests/neg-deep-subtype/enum-approx2.scala

This file was deleted.

24 changes: 0 additions & 24 deletions tests/pending/neg/i16451.check

This file was deleted.

20 changes: 20 additions & 0 deletions tests/warn/enum-approx2.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-- [E030] Match case Unreachable Warning: tests/warn/enum-approx2.scala:7:12 -------------------------------------------
7 | case Fun(x: Exp[Int => String]) => ??? // warn: unreachable // warn: unchecked
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
| Unreachable case
-- [E121] Pattern Match Warning: tests/warn/enum-approx2.scala:8:9 -----------------------------------------------------
8 | case _ => // warn: unreachable-only-null
| ^
| Unreachable case except for null (if this is intentional, consider writing case null => instead).
-- [E092] Pattern Match Unchecked Warning: tests/warn/enum-approx2.scala:6:13 ------------------------------------------
6 | case Fun(x: Fun[Int, Double]) => ??? // warn: unchecked
| ^
|the type test for Fun[Int, Double] cannot be checked at runtime because its type arguments can't be determined from Exp[Int => Int]
|
| longer explanation available when compiling with `-explain`
-- [E092] Pattern Match Unchecked Warning: tests/warn/enum-approx2.scala:7:13 ------------------------------------------
7 | case Fun(x: Exp[Int => String]) => ??? // warn: unreachable // warn: unchecked
| ^
|the type test for Exp[Int => String] cannot be checked at runtime because its type arguments can't be determined from Exp[Int => Int]
|
| longer explanation available when compiling with `-explain`
10 changes: 10 additions & 0 deletions tests/warn/enum-approx2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
sealed trait Exp[T]
case class Fun[A, B](f: Exp[A => B]) extends Exp[A => B]

class Test {
def eval(e: Fun[Int, Int]) = e match {
case Fun(x: Fun[Int, Double]) => ??? // warn: unchecked
case Fun(x: Exp[Int => String]) => ??? // warn: unreachable // warn: unchecked
case _ => // warn: unreachable-only-null
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//> using options -Xfatal-warnings

trait Box[+T]
case class Foo[+S](s: S) extends Box[S]

Expand Down
56 changes: 56 additions & 0 deletions tests/warn/i16451.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
-- [E030] Match case Unreachable Warning: tests/warn/i16451.scala:14:9 -------------------------------------------------
14 | case x: Wrapper[Color.Green.type] => None // warn: unreachable // warn: unchecked
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| Unreachable case
-- [E030] Match case Unreachable Warning: tests/warn/i16451.scala:22:9 -------------------------------------------------
22 | case x: Wrapper[Color.Green.type] => None // warn: unreachable // warn: unchecked
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| Unreachable case
-- [E092] Pattern Match Unchecked Warning: tests/warn/i16451.scala:13:9 ------------------------------------------------
13 | case x: Wrapper[Color.Red.type] => Some(x) // warn: unchecked
| ^
|the type test for Wrapper[(Color.Red : Color)] cannot be checked at runtime because its type arguments can't be determined from Wrapper[Color]
|
| longer explanation available when compiling with `-explain`
-- [E092] Pattern Match Unchecked Warning: tests/warn/i16451.scala:14:9 ------------------------------------------------
14 | case x: Wrapper[Color.Green.type] => None // warn: unreachable // warn: unchecked
| ^
|the type test for Wrapper[(Color.Green : Color)] cannot be checked at runtime because its type arguments can't be determined from Wrapper[Color]
|
| longer explanation available when compiling with `-explain`
-- [E092] Pattern Match Unchecked Warning: tests/warn/i16451.scala:21:9 ------------------------------------------------
21 | case x: Wrapper[Color.Red.type] => Some(x) // warn: unchecked
| ^
|the type test for Wrapper[(Color.Red : Color)] cannot be checked at runtime because its type arguments can't be determined from Any
|
| longer explanation available when compiling with `-explain`
-- [E092] Pattern Match Unchecked Warning: tests/warn/i16451.scala:22:9 ------------------------------------------------
22 | case x: Wrapper[Color.Green.type] => None // warn: unreachable // warn: unchecked
| ^
|the type test for Wrapper[(Color.Green : Color)] cannot be checked at runtime because its type arguments can't be determined from Any
|
| longer explanation available when compiling with `-explain`
-- [E092] Pattern Match Unchecked Warning: tests/warn/i16451.scala:25:9 ------------------------------------------------
25 | case x: Wrapper[Color.Red.type] => Some(x) // error: unreachable // error: unchecked
| ^
|the type test for Wrapper[(Color.Red : Color)] cannot be checked at runtime because its type arguments can't be determined from Wrapper[Color]
|
| longer explanation available when compiling with `-explain`
-- [E092] Pattern Match Unchecked Warning: tests/warn/i16451.scala:29:9 ------------------------------------------------
29 | case x: Wrapper[Color.Red.type] => Some(x)
| ^
|the type test for Wrapper[(Color.Red : Color)] cannot be checked at runtime because its type arguments can't be determined from A1
|
| longer explanation available when compiling with `-explain`
-- [E092] Pattern Match Unchecked Warning: tests/warn/i16451.scala:34:11 -----------------------------------------------
34 | case x: Wrapper[Color.Red.type] => x
| ^
|the type test for Wrapper[(Color.Red : Color)] cannot be checked at runtime because its type arguments can't be determined from Wrapper[Color]
|
| longer explanation available when compiling with `-explain`
-- [E092] Pattern Match Unchecked Warning: tests/warn/i16451.scala:39:11 -----------------------------------------------
39 | case x: Wrapper[Color.Red.type] => x
| ^
|the type test for Wrapper[(Color.Red : Color)] cannot be checked at runtime because its type arguments can't be determined from Wrapper[Color]
|
| longer explanation available when compiling with `-explain`
22 changes: 13 additions & 9 deletions tests/pending/neg/i16451.scala → tests/warn/i16451.scala
Original file line number Diff line number Diff line change
@@ -1,38 +1,42 @@
//> using options -Werror
//
enum Color:
case Red, Green
//sealed trait Color
//object Color:
// case object Red extends Color
// case object Green extends Color

case class Wrapper[A](value: A)

object Test:
def test_correct(x: Wrapper[Color]): Option[Wrapper[Color.Red.type]] = x match
case x: Wrapper[Color.Red.type] => Some(x) // error
case null => None
case x: Wrapper[Color.Red.type] => Some(x) // warn: unchecked
case x: Wrapper[Color.Green.type] => None // warn: unreachable // warn: unchecked

def test_different(x: Wrapper[Color]): Option[Wrapper[Color]] = x match
case x @ Wrapper(_: Color.Red.type) => Some(x)
case x @ Wrapper(_: Color.Green.type) => None

def test_any(x: Any): Option[Wrapper[Color.Red.type]] = x match
case x: Wrapper[Color.Red.type] => Some(x) // error
case _ => None
case x: Wrapper[Color.Red.type] => Some(x) // warn: unchecked
case x: Wrapper[Color.Green.type] => None // warn: unreachable // warn: unchecked

def test_wrong(x: Wrapper[Color]): Option[Wrapper[Color.Red.type]] = x match
case x: Wrapper[Color.Red.type] => Some(x) // error
case x: Wrapper[Color.Red.type] => Some(x) // error: unreachable // error: unchecked
case null => None

def t2[A1 <: Wrapper[Color]](x: A1): Option[Wrapper[Color.Red.type]] = x match
case x: Wrapper[Color.Red.type] => Some(x) // error
case x: Wrapper[Color.Red.type] => Some(x)
case null => None

def test_wrong_seq(xs: Seq[Wrapper[Color]]): Seq[Wrapper[Color.Red.type]] =
xs.collect {
case x: Wrapper[Color.Red.type] => x // error
case x: Wrapper[Color.Red.type] => x
}

def test_wrong_seq2(xs: Seq[Wrapper[Color]]): Seq[Wrapper[Color.Red.type]] =
xs.collect { x => x match
case x: Wrapper[Color.Red.type] => x // error
case x: Wrapper[Color.Red.type] => x
}

def main(args: Array[String]): Unit =
Expand Down
34 changes: 34 additions & 0 deletions tests/warn/i5826.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
-- [E121] Pattern Match Warning: tests/warn/i5826.scala:9:9 ------------------------------------------------------------
9 | case _ => 0 // warn: unreachable-only-null
| ^
| Unreachable case except for null (if this is intentional, consider writing case null => instead).
-- [E092] Pattern Match Unchecked Warning: tests/warn/i5826.scala:3:9 --------------------------------------------------
3 | case ls: List[Int] => ls.head // error, A = List[String]
| ^
| the type test for List[Int] cannot be checked at runtime because its type arguments can't be determined from A
|
| longer explanation available when compiling with `-explain`
-- [E092] Pattern Match Unchecked Warning: tests/warn/i5826.scala:8:9 --------------------------------------------------
8 | case ls: List[Int] => ls.head // warn: unchecked
| ^
|the type test for List[Int] cannot be checked at runtime because its type arguments can't be determined from List[String]
|
| longer explanation available when compiling with `-explain`
-- [E092] Pattern Match Unchecked Warning: tests/warn/i5826.scala:17:9 -------------------------------------------------
17 | case ls: A[X] => 4 // error
| ^
|the type test for Foo.this.A[X] cannot be checked at runtime because its type arguments can't be determined from Foo.this.B[X]
|
| longer explanation available when compiling with `-explain`
-- [E092] Pattern Match Unchecked Warning: tests/warn/i5826.scala:22:9 -------------------------------------------------
22 | case ls: List[Int] => ls.head // error, List extends Int => T
| ^
|the type test for List[Int] cannot be checked at runtime because its type arguments can't be determined from A => Int
|
| longer explanation available when compiling with `-explain`
-- [E092] Pattern Match Unchecked Warning: tests/warn/i5826.scala:28:54 ------------------------------------------------
28 | def test5[T](x: A[T] | B[T] | Option[T]): Boolean = x.isInstanceOf[C[String]] // error
| ^
|the type test for Foo.this.C[String] cannot be checked at runtime because its type arguments can't be determined from Foo.this.A[T]
|
| longer explanation available when compiling with `-explain`
6 changes: 2 additions & 4 deletions tests/neg-deep-subtype/i5826.scala → tests/warn/i5826.scala
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
//> using options -Xfatal-warnings

class Foo {
def test[A]: (List[Int] | A) => Int = {
case ls: List[Int] => ls.head // error, A = List[String]
case _ => 0
}

def test2: List[Int] | List[String] => Int = {
case ls: List[Int] => ls.head // error
case _ => 0
case ls: List[Int] => ls.head // warn: unchecked
case _ => 0 // warn: unreachable-only-null
}

trait A[T]
Expand Down
2 changes: 0 additions & 2 deletions tests/neg-deep-subtype/i8932.scala → tests/warn/i8932.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//> using options -Xfatal-warnings

sealed trait Foo[+A]
case class Bar[A]() extends Foo[A]

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//> using options -Xfatal-warnings

object Test {
sealed trait Foo[A, B]
final case class Bar[X](x: X) extends Foo[X, X]
Expand Down

0 comments on commit 9045834

Please sign in to comment.