Skip to content

Commit 333fa6c

Browse files
dwijnandWojciechMazur
authored andcommitted
Unsuppress unchecked warnings
And check it with a pos checkfile. [Cherry-picked 9045834]
1 parent e576ac6 commit 333fa6c

15 files changed

+148
-65
lines changed

compiler/src/dotty/tools/dotc/reporting/Message.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ abstract class Message(val errorId: ErrorMessageID)(using Context) { self =>
377377
override def canExplain = true
378378

379379
/** Override with `true` for messages that should always be shown even if their
380-
* position overlaps another messsage of a different class. On the other hand
380+
* position overlaps another message of a different class. On the other hand
381381
* multiple messages of the same class with overlapping positions will lead
382382
* to only a single message of that class to be issued.
383383
*/

compiler/src/dotty/tools/dotc/reporting/messages.scala

+1
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,7 @@ extends Message(PatternMatchExhaustivityID) {
897897

898898
class UncheckedTypePattern(argType: Type, whyNot: String)(using Context)
899899
extends PatternMatchMsg(UncheckedTypePatternID) {
900+
override def showAlways = true
900901
def msg(using Context) = i"the type test for $argType cannot be checked at runtime because $whyNot"
901902
def explain(using Context) =
902903
i"""|Type arguments and type refinements are erased during compile time, thus it's

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ object TypeTestsCasts {
7474
}.apply(tp)
7575

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

8080
def underlyingLambda(tp: Type): TypeLambda = tp.ensureLambdaSub match {
@@ -155,7 +155,7 @@ object TypeTestsCasts {
155155
case x =>
156156
// always false test warnings are emitted elsewhere
157157
TypeComparer.provablyDisjoint(x, tpe.derivedAppliedType(tycon, targs.map(_ => WildcardType)))
158-
|| typeArgsTrivial(X, tpe)
158+
|| typeArgsDeterminable(X, tpe)
159159
||| i"its type arguments can't be determined from $X"
160160
}
161161
case AndType(tp1, tp2) => recur(X, tp1) && recur(X, tp2)

compiler/src/dotty/tools/dotc/transform/patmat/Space.scala

+9-7
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ object SpaceEngine {
394394
project(pat)
395395

396396
case Typed(_, tpt) =>
397-
Typ(erase(tpt.tpe.stripAnnots, isValue = true), decomposed = false)
397+
Typ(erase(tpt.tpe.stripAnnots, isValue = true, isTyped = true), decomposed = false)
398398

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

470470
case tp @ AppliedType(tycon, args) =>
471471
val inArray = tycon.isRef(defn.ArrayClass)
472-
val args2 = args.map(arg => erase(arg, inArray = inArray, isValue = false))
472+
val args2 =
473+
if isTyped && !inArray then args.map(_ => WildcardType)
474+
else args.map(arg => erase(arg, inArray = inArray, isValue = false))
473475
tp.derivedAppliedType(erase(tycon, inArray, isValue = false), args2)
474476

475477
case tp @ OrType(tp1, tp2) =>
476-
OrType(erase(tp1, inArray, isValue), erase(tp2, inArray, isValue), tp.isSoft)
478+
OrType(erase(tp1, inArray, isValue, isTyped), erase(tp2, inArray, isValue, isTyped), tp.isSoft)
477479

478480
case AndType(tp1, tp2) =>
479-
AndType(erase(tp1, inArray, isValue), erase(tp2, inArray, isValue))
481+
AndType(erase(tp1, inArray, isValue, isTyped), erase(tp2, inArray, isValue, isTyped))
480482

481483
case tp @ RefinedType(parent, _, _) =>
482-
erase(parent, inArray, isValue)
484+
erase(parent, inArray, isValue, isTyped)
483485

484486
case tref: TypeRef if tref.symbol.isPatternBound =>
485487
if inArray then tref.underlying

tests/neg-deep-subtype/enum-approx2.scala

-12
This file was deleted.

tests/pending/neg/i16451.check

-24
This file was deleted.

tests/warn/enum-approx2.check

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-- [E030] Match case Unreachable Warning: tests/warn/enum-approx2.scala:7:12 -------------------------------------------
2+
7 | case Fun(x: Exp[Int => String]) => ??? // warn: unreachable // warn: unchecked
3+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
4+
| Unreachable case
5+
-- [E121] Pattern Match Warning: tests/warn/enum-approx2.scala:8:9 -----------------------------------------------------
6+
8 | case _ => // warn: unreachable-only-null
7+
| ^
8+
| Unreachable case except for null (if this is intentional, consider writing case null => instead).
9+
-- [E092] Pattern Match Unchecked Warning: tests/warn/enum-approx2.scala:6:13 ------------------------------------------
10+
6 | case Fun(x: Fun[Int, Double]) => ??? // warn: unchecked
11+
| ^
12+
|the type test for Fun[Int, Double] cannot be checked at runtime because its type arguments can't be determined from Exp[Int => Int]
13+
|
14+
| longer explanation available when compiling with `-explain`
15+
-- [E092] Pattern Match Unchecked Warning: tests/warn/enum-approx2.scala:7:13 ------------------------------------------
16+
7 | case Fun(x: Exp[Int => String]) => ??? // warn: unreachable // warn: unchecked
17+
| ^
18+
|the type test for Exp[Int => String] cannot be checked at runtime because its type arguments can't be determined from Exp[Int => Int]
19+
|
20+
| longer explanation available when compiling with `-explain`

tests/warn/enum-approx2.scala

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
sealed trait Exp[T]
2+
case class Fun[A, B](f: Exp[A => B]) extends Exp[A => B]
3+
4+
class Test {
5+
def eval(e: Fun[Int, Int]) = e match {
6+
case Fun(x: Fun[Int, Double]) => ??? // warn: unchecked
7+
case Fun(x: Exp[Int => String]) => ??? // warn: unreachable // warn: unchecked
8+
case _ => // warn: unreachable-only-null
9+
}
10+
}

tests/neg-deep-subtype/i11178.scala renamed to tests/warn/i11178.scala

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
//> using options -Xfatal-warnings
2-
31
trait Box[+T]
42
case class Foo[+S](s: S) extends Box[S]
53

tests/warn/i16451.check

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
-- [E030] Match case Unreachable Warning: tests/warn/i16451.scala:14:9 -------------------------------------------------
2+
14 | case x: Wrapper[Color.Green.type] => None // warn: unreachable // warn: unchecked
3+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4+
| Unreachable case
5+
-- [E030] Match case Unreachable Warning: tests/warn/i16451.scala:22:9 -------------------------------------------------
6+
22 | case x: Wrapper[Color.Green.type] => None // warn: unreachable // warn: unchecked
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8+
| Unreachable case
9+
-- [E092] Pattern Match Unchecked Warning: tests/warn/i16451.scala:13:9 ------------------------------------------------
10+
13 | case x: Wrapper[Color.Red.type] => Some(x) // warn: unchecked
11+
| ^
12+
|the type test for Wrapper[(Color.Red : Color)] cannot be checked at runtime because its type arguments can't be determined from Wrapper[Color]
13+
|
14+
| longer explanation available when compiling with `-explain`
15+
-- [E092] Pattern Match Unchecked Warning: tests/warn/i16451.scala:14:9 ------------------------------------------------
16+
14 | case x: Wrapper[Color.Green.type] => None // warn: unreachable // warn: unchecked
17+
| ^
18+
|the type test for Wrapper[(Color.Green : Color)] cannot be checked at runtime because its type arguments can't be determined from Wrapper[Color]
19+
|
20+
| longer explanation available when compiling with `-explain`
21+
-- [E092] Pattern Match Unchecked Warning: tests/warn/i16451.scala:21:9 ------------------------------------------------
22+
21 | case x: Wrapper[Color.Red.type] => Some(x) // warn: unchecked
23+
| ^
24+
|the type test for Wrapper[(Color.Red : Color)] cannot be checked at runtime because its type arguments can't be determined from Any
25+
|
26+
| longer explanation available when compiling with `-explain`
27+
-- [E092] Pattern Match Unchecked Warning: tests/warn/i16451.scala:22:9 ------------------------------------------------
28+
22 | case x: Wrapper[Color.Green.type] => None // warn: unreachable // warn: unchecked
29+
| ^
30+
|the type test for Wrapper[(Color.Green : Color)] cannot be checked at runtime because its type arguments can't be determined from Any
31+
|
32+
| longer explanation available when compiling with `-explain`
33+
-- [E092] Pattern Match Unchecked Warning: tests/warn/i16451.scala:25:9 ------------------------------------------------
34+
25 | case x: Wrapper[Color.Red.type] => Some(x) // error: unreachable // error: unchecked
35+
| ^
36+
|the type test for Wrapper[(Color.Red : Color)] cannot be checked at runtime because its type arguments can't be determined from Wrapper[Color]
37+
|
38+
| longer explanation available when compiling with `-explain`
39+
-- [E092] Pattern Match Unchecked Warning: tests/warn/i16451.scala:29:9 ------------------------------------------------
40+
29 | case x: Wrapper[Color.Red.type] => Some(x)
41+
| ^
42+
|the type test for Wrapper[(Color.Red : Color)] cannot be checked at runtime because its type arguments can't be determined from A1
43+
|
44+
| longer explanation available when compiling with `-explain`
45+
-- [E092] Pattern Match Unchecked Warning: tests/warn/i16451.scala:34:11 -----------------------------------------------
46+
34 | case x: Wrapper[Color.Red.type] => x
47+
| ^
48+
|the type test for Wrapper[(Color.Red : Color)] cannot be checked at runtime because its type arguments can't be determined from Wrapper[Color]
49+
|
50+
| longer explanation available when compiling with `-explain`
51+
-- [E092] Pattern Match Unchecked Warning: tests/warn/i16451.scala:39:11 -----------------------------------------------
52+
39 | case x: Wrapper[Color.Red.type] => x
53+
| ^
54+
|the type test for Wrapper[(Color.Red : Color)] cannot be checked at runtime because its type arguments can't be determined from Wrapper[Color]
55+
|
56+
| longer explanation available when compiling with `-explain`

tests/pending/neg/i16451.scala renamed to tests/warn/i16451.scala

+13-9
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,42 @@
1-
//> using options -Werror
1+
//
22
enum Color:
33
case Red, Green
4+
//sealed trait Color
5+
//object Color:
6+
// case object Red extends Color
7+
// case object Green extends Color
48

59
case class Wrapper[A](value: A)
610

711
object Test:
812
def test_correct(x: Wrapper[Color]): Option[Wrapper[Color.Red.type]] = x match
9-
case x: Wrapper[Color.Red.type] => Some(x) // error
10-
case null => None
13+
case x: Wrapper[Color.Red.type] => Some(x) // warn: unchecked
14+
case x: Wrapper[Color.Green.type] => None // warn: unreachable // warn: unchecked
1115

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

1620
def test_any(x: Any): Option[Wrapper[Color.Red.type]] = x match
17-
case x: Wrapper[Color.Red.type] => Some(x) // error
18-
case _ => None
21+
case x: Wrapper[Color.Red.type] => Some(x) // warn: unchecked
22+
case x: Wrapper[Color.Green.type] => None // warn: unreachable // warn: unchecked
1923

2024
def test_wrong(x: Wrapper[Color]): Option[Wrapper[Color.Red.type]] = x match
21-
case x: Wrapper[Color.Red.type] => Some(x) // error
25+
case x: Wrapper[Color.Red.type] => Some(x) // error: unreachable // error: unchecked
2226
case null => None
2327

2428
def t2[A1 <: Wrapper[Color]](x: A1): Option[Wrapper[Color.Red.type]] = x match
25-
case x: Wrapper[Color.Red.type] => Some(x) // error
29+
case x: Wrapper[Color.Red.type] => Some(x)
2630
case null => None
2731

2832
def test_wrong_seq(xs: Seq[Wrapper[Color]]): Seq[Wrapper[Color.Red.type]] =
2933
xs.collect {
30-
case x: Wrapper[Color.Red.type] => x // error
34+
case x: Wrapper[Color.Red.type] => x
3135
}
3236

3337
def test_wrong_seq2(xs: Seq[Wrapper[Color]]): Seq[Wrapper[Color.Red.type]] =
3438
xs.collect { x => x match
35-
case x: Wrapper[Color.Red.type] => x // error
39+
case x: Wrapper[Color.Red.type] => x
3640
}
3741

3842
def main(args: Array[String]): Unit =

tests/warn/i5826.check

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
-- [E121] Pattern Match Warning: tests/warn/i5826.scala:9:9 ------------------------------------------------------------
2+
9 | case _ => 0 // warn: unreachable-only-null
3+
| ^
4+
| Unreachable case except for null (if this is intentional, consider writing case null => instead).
5+
-- [E092] Pattern Match Unchecked Warning: tests/warn/i5826.scala:3:9 --------------------------------------------------
6+
3 | case ls: List[Int] => ls.head // error, A = List[String]
7+
| ^
8+
| the type test for List[Int] cannot be checked at runtime because its type arguments can't be determined from A
9+
|
10+
| longer explanation available when compiling with `-explain`
11+
-- [E092] Pattern Match Unchecked Warning: tests/warn/i5826.scala:8:9 --------------------------------------------------
12+
8 | case ls: List[Int] => ls.head // warn: unchecked
13+
| ^
14+
|the type test for List[Int] cannot be checked at runtime because its type arguments can't be determined from List[String]
15+
|
16+
| longer explanation available when compiling with `-explain`
17+
-- [E092] Pattern Match Unchecked Warning: tests/warn/i5826.scala:17:9 -------------------------------------------------
18+
17 | case ls: A[X] => 4 // error
19+
| ^
20+
|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]
21+
|
22+
| longer explanation available when compiling with `-explain`
23+
-- [E092] Pattern Match Unchecked Warning: tests/warn/i5826.scala:22:9 -------------------------------------------------
24+
22 | case ls: List[Int] => ls.head // error, List extends Int => T
25+
| ^
26+
|the type test for List[Int] cannot be checked at runtime because its type arguments can't be determined from A => Int
27+
|
28+
| longer explanation available when compiling with `-explain`
29+
-- [E092] Pattern Match Unchecked Warning: tests/warn/i5826.scala:28:54 ------------------------------------------------
30+
28 | def test5[T](x: A[T] | B[T] | Option[T]): Boolean = x.isInstanceOf[C[String]] // error
31+
| ^
32+
|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]
33+
|
34+
| longer explanation available when compiling with `-explain`

tests/neg-deep-subtype/i5826.scala renamed to tests/warn/i5826.scala

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
//> using options -Xfatal-warnings
2-
31
class Foo {
42
def test[A]: (List[Int] | A) => Int = {
53
case ls: List[Int] => ls.head // error, A = List[String]
64
case _ => 0
75
}
86

97
def test2: List[Int] | List[String] => Int = {
10-
case ls: List[Int] => ls.head // error
11-
case _ => 0
8+
case ls: List[Int] => ls.head // warn: unchecked
9+
case _ => 0 // warn: unreachable-only-null
1210
}
1311

1412
trait A[T]

tests/neg-deep-subtype/i8932.scala renamed to tests/warn/i8932.scala

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
//> using options -Xfatal-warnings
2-
31
sealed trait Foo[+A]
42
case class Bar[A]() extends Foo[A]
53

tests/neg/suppressed-type-test-warnings.scala renamed to tests/warn/suppressed-type-test-warnings.scala

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
//> using options -Xfatal-warnings
2-
31
object Test {
42
sealed trait Foo[A, B]
53
final case class Bar[X](x: X) extends Foo[X, X]

0 commit comments

Comments
 (0)