From 96ec1aad6e7dd2a93e380f95943063884b528002 Mon Sep 17 00:00:00 2001 From: Szymon Rodziewicz Date: Fri, 15 Dec 2023 16:31:09 +0100 Subject: [PATCH 1/2] Second batch of neg -> warn test changes --- tests/neg/14034b.scala | 15 ----- tests/neg/17284.scala | 14 ----- tests/neg/18493.check | 8 --- tests/neg/avoid-warn-deprecation.scala | 11 ---- tests/neg/main-functions-nameclash.scala | 5 -- tests/neg/manifest-summoning-b.scala | 4 -- tests/neg/matchable.scala | 29 --------- tests/neg/old-syntax.scala | 5 -- tests/neg/ovlazy.scala | 8 --- tests/neg/private-this-3.4.scala | 7 --- tests/neg/private-this-future-migration.scala | 7 --- tests/neg/quote-simple-hole.scala | 17 ------ tests/neg/refinements-this.scala | 5 -- .../refutable-pattern-binding-messages.check | 12 ++-- .../refutable-pattern-binding-messages.scala | 8 +-- tests/neg/rewrite-messages.scala | 8 --- tests/neg/strict-pattern-bindings-3.2.scala | 37 ------------ tests/neg/symbolic-packages.scala | 13 ---- tests/neg/warn-value-discard.check | 20 ------- .../with-type-operator-future-migration.scala | 5 -- tests/warn/14034b.scala | 15 +++++ tests/{neg => warn}/15981.check | 4 +- tests/{neg => warn}/15981.scala | 4 +- tests/{neg => warn}/17284.check | 12 ++-- tests/warn/17284.scala | 14 +++++ tests/warn/1828.scala | 11 ++++ tests/warn/18493.check | 8 +++ tests/{neg => warn}/18493.scala | 6 +- tests/warn/3324b.scala | 11 ++++ tests/warn/3324f.scala | 11 ++++ tests/warn/3324g.scala | 21 +++++++ .../{neg => warn}/IsInstanceOfClassTag2.scala | 5 +- tests/warn/JavaSeqLiteral.scala | 31 ++++++++++ tests/warn/avoid-warn-deprecation.scala | 11 ++++ tests/warn/conditionalWarnings.scala | 15 +++++ tests/{neg => warn}/convertible.scala | 11 ++-- tests/{neg => warn}/deprecated-override.scala | 7 +-- tests/{neg => warn}/feature-shadowing.scala | 4 +- .../gadt-contradictory-pattern.scala | 8 +-- tests/warn/gadt.scala | 15 +++++ tests/warn/html.scala | 20 +++++++ tests/warn/main-functions-nameclash.scala | 5 ++ .../{neg => warn}/manifest-summoning-b.check | 8 +-- tests/warn/manifest-summoning-b.scala | 4 ++ tests/warn/matchable.scala | 28 +++++++++ tests/{neg => warn}/newline-braces.scala | 5 +- tests/{neg => warn}/nonunit-statement.scala | 47 ++++++++------- tests/warn/old-syntax.scala | 5 ++ tests/{neg => warn}/opaque-match.scala | 14 ++--- tests/warn/or-type-trees.scala | 40 +++++++++++++ tests/warn/ovlazy.scala | 9 +++ tests/{neg => warn}/private-this-3.4.check | 8 +-- tests/warn/private-this-3.4.scala | 5 ++ .../warn/private-this-future-migration.scala | 5 ++ tests/warn/quote-simple-hole.scala | 17 ++++++ tests/warn/refined-types.scala | 24 ++++++++ tests/warn/refinements-this.scala | 6 ++ tests/{neg => warn}/rewrite-messages.check | 8 +-- tests/warn/rewrite-messages.scala | 8 +++ .../scala2-t11681.scala | 11 ++-- tests/warn/strict-pattern-bindings-3.2.scala | 37 ++++++++++++ tests/{neg => warn}/supertraits-b.scala | 12 ++-- tests/{neg => warn}/switches.scala | 16 ++--- tests/{neg => warn}/symbolic-packages.check | 16 ++--- tests/warn/symbolic-packages.scala | 13 ++++ tests/warn/t2755.scala | 60 +++++++++++++++++++ tests/{neg => warn}/t3235-minimal.check | 16 ++--- tests/{neg => warn}/t3235-minimal.scala | 12 ++-- tests/{neg => warn}/t5830.scala | 4 +- tests/warn/type-lambda.scala | 16 +++++ tests/{neg => warn}/type-test-paths-2.scala | 12 ++-- tests/{neg => warn}/type-test-paths.scala | 4 +- .../{neg => warn}/type-test-syntesize-b.scala | 10 ++-- tests/{neg => warn}/uninitialized-3.4.check | 4 +- tests/{neg => warn}/uninitialized-3.4.scala | 4 +- .../uninitialized-future-migration.scala | 4 +- tests/warn/warn-value-discard.check | 20 +++++++ tests/{neg => warn}/warn-value-discard.scala | 14 ++--- .../with-type-operator-future-migration.check | 4 +- .../with-type-operator-future-migration.scala | 6 ++ tests/{neg => warn}/xfatalWarnings.scala | 6 +- 81 files changed, 648 insertions(+), 381 deletions(-) delete mode 100644 tests/neg/14034b.scala delete mode 100644 tests/neg/17284.scala delete mode 100644 tests/neg/18493.check delete mode 100644 tests/neg/avoid-warn-deprecation.scala delete mode 100644 tests/neg/main-functions-nameclash.scala delete mode 100644 tests/neg/manifest-summoning-b.scala delete mode 100644 tests/neg/matchable.scala delete mode 100644 tests/neg/old-syntax.scala delete mode 100644 tests/neg/ovlazy.scala delete mode 100644 tests/neg/private-this-3.4.scala delete mode 100644 tests/neg/private-this-future-migration.scala delete mode 100644 tests/neg/quote-simple-hole.scala delete mode 100644 tests/neg/refinements-this.scala delete mode 100644 tests/neg/rewrite-messages.scala delete mode 100644 tests/neg/strict-pattern-bindings-3.2.scala delete mode 100644 tests/neg/symbolic-packages.scala delete mode 100644 tests/neg/warn-value-discard.check delete mode 100644 tests/neg/with-type-operator-future-migration.scala create mode 100644 tests/warn/14034b.scala rename tests/{neg => warn}/15981.check (68%) rename tests/{neg => warn}/15981.scala (76%) rename tests/{neg => warn}/17284.check (86%) create mode 100644 tests/warn/17284.scala create mode 100644 tests/warn/1828.scala create mode 100644 tests/warn/18493.check rename tests/{neg => warn}/18493.scala (68%) create mode 100644 tests/warn/3324b.scala create mode 100644 tests/warn/3324f.scala create mode 100644 tests/warn/3324g.scala rename tests/{neg => warn}/IsInstanceOfClassTag2.scala (80%) create mode 100644 tests/warn/JavaSeqLiteral.scala create mode 100644 tests/warn/avoid-warn-deprecation.scala create mode 100644 tests/warn/conditionalWarnings.scala rename tests/{neg => warn}/convertible.scala (60%) rename tests/{neg => warn}/deprecated-override.scala (52%) rename tests/{neg => warn}/feature-shadowing.scala (77%) rename tests/{neg => warn}/gadt-contradictory-pattern.scala (54%) create mode 100644 tests/warn/gadt.scala create mode 100644 tests/warn/html.scala create mode 100644 tests/warn/main-functions-nameclash.scala rename tests/{neg => warn}/manifest-summoning-b.check (73%) create mode 100644 tests/warn/manifest-summoning-b.scala create mode 100644 tests/warn/matchable.scala rename tests/{neg => warn}/newline-braces.scala (55%) rename tests/{neg => warn}/nonunit-statement.scala (80%) create mode 100644 tests/warn/old-syntax.scala rename tests/{neg => warn}/opaque-match.scala (63%) create mode 100644 tests/warn/or-type-trees.scala create mode 100644 tests/warn/ovlazy.scala rename tests/{neg => warn}/private-this-3.4.check (76%) create mode 100644 tests/warn/private-this-3.4.scala create mode 100644 tests/warn/private-this-future-migration.scala create mode 100644 tests/warn/quote-simple-hole.scala create mode 100644 tests/warn/refined-types.scala create mode 100644 tests/warn/refinements-this.scala rename tests/{neg => warn}/rewrite-messages.check (76%) create mode 100644 tests/warn/rewrite-messages.scala rename tests/{neg/i15503-scala2 => warn}/scala2-t11681.scala (90%) create mode 100644 tests/warn/strict-pattern-bindings-3.2.scala rename tests/{neg => warn}/supertraits-b.scala (69%) rename tests/{neg => warn}/switches.scala (77%) rename tests/{neg => warn}/symbolic-packages.check (65%) create mode 100644 tests/warn/symbolic-packages.scala create mode 100644 tests/warn/t2755.scala rename tests/{neg => warn}/t3235-minimal.check (75%) rename tests/{neg => warn}/t3235-minimal.scala (51%) rename tests/{neg => warn}/t5830.scala (63%) create mode 100644 tests/warn/type-lambda.scala rename tests/{neg => warn}/type-test-paths-2.scala (61%) rename tests/{neg => warn}/type-test-paths.scala (88%) rename tests/{neg => warn}/type-test-syntesize-b.scala (74%) rename tests/{neg => warn}/uninitialized-3.4.check (75%) rename tests/{neg => warn}/uninitialized-3.4.scala (60%) rename tests/{neg => warn}/uninitialized-future-migration.scala (62%) create mode 100644 tests/warn/warn-value-discard.check rename tests/{neg => warn}/warn-value-discard.scala (84%) rename tests/{neg => warn}/with-type-operator-future-migration.check (61%) create mode 100644 tests/warn/with-type-operator-future-migration.scala rename tests/{neg => warn}/xfatalWarnings.scala (69%) diff --git a/tests/neg/14034b.scala b/tests/neg/14034b.scala deleted file mode 100644 index 84f9ab3579c8..000000000000 --- a/tests/neg/14034b.scala +++ /dev/null @@ -1,15 +0,0 @@ -//> using options -Xfatal-warnings -deprecation - -@deprecated trait Exp -@deprecated val exp = 1 - -def test1 = exp // error -def test2(a: Exp) = () // error - -type Foo0 = Exp // error -type Foo = Option[Exp] // error -type Bar = Option[exp.type] // error -type Baz = Exp | Int // error -type Quux = [X] =>> X match - case Exp => Int // error -type Quuz[A <: Exp] = Int // error diff --git a/tests/neg/17284.scala b/tests/neg/17284.scala deleted file mode 100644 index 8f588233245a..000000000000 --- a/tests/neg/17284.scala +++ /dev/null @@ -1,14 +0,0 @@ -//> using options -Werror -explain - -def test = - 451.synchronized {} // error - -def test2 = - val x: Integer = 451 - x.synchronized {} // error - -def test3 = - true.synchronized {} // error - -def test4 = - true.hashCode() // success diff --git a/tests/neg/18493.check b/tests/neg/18493.check deleted file mode 100644 index 79a2872e71e8..000000000000 --- a/tests/neg/18493.check +++ /dev/null @@ -1,8 +0,0 @@ --- [E030] Match case Unreachable Error: tests/neg/18493.scala:6:9 ------------------------------------------------------ -6 | case "abc" => // error - | ^^^^^ - | Unreachable case --- [E030] Match case Unreachable Error: tests/neg/18493.scala:12:9 ----------------------------------------------------- -12 | case "abc" => // error - | ^^^^^ - | Unreachable case diff --git a/tests/neg/avoid-warn-deprecation.scala b/tests/neg/avoid-warn-deprecation.scala deleted file mode 100644 index 45baf7addb86..000000000000 --- a/tests/neg/avoid-warn-deprecation.scala +++ /dev/null @@ -1,11 +0,0 @@ -//> using options -Xfatal-warnings -feature - -object A { - @deprecated("use bar instead of this one", "0.2.3") - def foo: Int = 3 -} - -object B { - A.foo -} -// nopos-error there was 1 deprecation warning; re-run with -deprecation for details diff --git a/tests/neg/main-functions-nameclash.scala b/tests/neg/main-functions-nameclash.scala deleted file mode 100644 index 1f9352e1592d..000000000000 --- a/tests/neg/main-functions-nameclash.scala +++ /dev/null @@ -1,5 +0,0 @@ -//> using options -Xfatal-warnings - -object foo { - @main def foo(x: Int) = () // error: class foo and object foo produce classes that overwrite one another -} diff --git a/tests/neg/manifest-summoning-b.scala b/tests/neg/manifest-summoning-b.scala deleted file mode 100644 index 6d1b8baff007..000000000000 --- a/tests/neg/manifest-summoning-b.scala +++ /dev/null @@ -1,4 +0,0 @@ -//> using options -Xfatal-warnings -deprecation - -val foo = manifest[List[? <: Int]] // error -val bar = optManifest[Array[? <: String]] // error diff --git a/tests/neg/matchable.scala b/tests/neg/matchable.scala deleted file mode 100644 index aaf8234f6d1e..000000000000 --- a/tests/neg/matchable.scala +++ /dev/null @@ -1,29 +0,0 @@ -//> using options -Xfatal-warnings -source future - -def foo[T](x: T): Matchable = - println(x.getClass()) // ok - println(x.isInstanceOf[Int]) // ok - x match - case x: Int => // error: should not be scrutinized - println("int") - x - case x: String => // error: should not be scrutinized - println("string") - x - List(x) match - case (x: Int) :: Nil => // error: should not be scrutinized - println("int") - x - case List(x: String) => // error: should not be scrutinized - println("string") - x - case List(y :: Nil) => // error: should not be scrutinized - y :: Nil - case _ => - x // error: should not be scrutinized - -@main def Test = - val x: Matchable = foo(1) - val y: Matchable = foo("hello") - assert(x != y) - diff --git a/tests/neg/old-syntax.scala b/tests/neg/old-syntax.scala deleted file mode 100644 index 124781d13db2..000000000000 --- a/tests/neg/old-syntax.scala +++ /dev/null @@ -1,5 +0,0 @@ -//> using options -Xfatal-warnings -deprecation - -val f = (x: Int) ⇒ x + 1 // error - -val list = for (n ← List(42)) yield n + 1 // error diff --git a/tests/neg/ovlazy.scala b/tests/neg/ovlazy.scala deleted file mode 100644 index 69078fbd2745..000000000000 --- a/tests/neg/ovlazy.scala +++ /dev/null @@ -1,8 +0,0 @@ -//> using options -source 3.0-migration -Xfatal-warnings - -class A { - val x: Int = 1 -} -class B extends A { - override lazy val x: Int = 2 // error -} diff --git a/tests/neg/private-this-3.4.scala b/tests/neg/private-this-3.4.scala deleted file mode 100644 index b198e954e41b..000000000000 --- a/tests/neg/private-this-3.4.scala +++ /dev/null @@ -1,7 +0,0 @@ -//> using options -Werror - -import scala.language.`3.4` - -class Foo: - private[this] def foo: Int = ??? // error: migration warning - protected[this] def bar: Int = ??? // error: migration warning diff --git a/tests/neg/private-this-future-migration.scala b/tests/neg/private-this-future-migration.scala deleted file mode 100644 index 7e3da2be72e2..000000000000 --- a/tests/neg/private-this-future-migration.scala +++ /dev/null @@ -1,7 +0,0 @@ -//> using options -Werror - -import scala.language.`future-migration` - -class Foo: - private[this] def foo: Int = ??? // error: migration warning - protected[this] def bar: Int = ??? // error: migration warning diff --git a/tests/neg/quote-simple-hole.scala b/tests/neg/quote-simple-hole.scala deleted file mode 100644 index 64e2bcad4862..000000000000 --- a/tests/neg/quote-simple-hole.scala +++ /dev/null @@ -1,17 +0,0 @@ -//> using options -Xfatal-warnings - -import scala.quoted.Quotes - -def test(using Quotes) = { - val x = '{0} - val y = '{ // error: Canceled splice directly inside a quote. '{ ${ XYZ } } is equivalent to XYZ. - $x - } - val z = '{ - val a = ${ // error: Canceled quote directly inside a splice. ${ '{ XYZ } } is equivalent to XYZ. - '{ - $y - } - } - } -} diff --git a/tests/neg/refinements-this.scala b/tests/neg/refinements-this.scala deleted file mode 100644 index f8d41bd85360..000000000000 --- a/tests/neg/refinements-this.scala +++ /dev/null @@ -1,5 +0,0 @@ -//> using options -Xfatal-warnings - -class Outer: - type X = { type O = Outer.this.type } // ok - type Y = { type O = this.type } // error diff --git a/tests/neg/refutable-pattern-binding-messages.check b/tests/neg/refutable-pattern-binding-messages.check index 5a9d85fd4447..4a8f895264a3 100644 --- a/tests/neg/refutable-pattern-binding-messages.check +++ b/tests/neg/refutable-pattern-binding-messages.check @@ -22,24 +22,24 @@ | If the narrowing is intentional, this can be communicated by adding the `case` keyword before the full pattern, | which will result in a filtering for expression (using `withFilter`). | This patch can be rewritten automatically under -rewrite -source 3.2-migration. --- Error: tests/neg/refutable-pattern-binding-messages.scala:5:14 ------------------------------------------------------ -5 | val Positive(p) = 5 // error: refutable extractor +-- Warning: tests/neg/refutable-pattern-binding-messages.scala:5:14 ---------------------------------------------------- +5 | val Positive(p) = 5 // warn: refutable extractor | ^^^^^^^^^^^^^^^ | pattern binding uses refutable extractor `Test.Positive` | | If this usage is intentional, this can be communicated by adding `: @unchecked` after the expression, | which may result in a MatchError at runtime. | This patch can be rewritten automatically under -rewrite -source 3.2-migration. --- Error: tests/neg/refutable-pattern-binding-messages.scala:10:20 ----------------------------------------------------- -10 | val i :: is = List(1, 2, 3) // error: pattern type more specialized +-- Warning: tests/neg/refutable-pattern-binding-messages.scala:10:20 --------------------------------------------------- +10 | val i :: is = List(1, 2, 3) // warn: pattern type more specialized | ^^^^^^^^^^^^^ | pattern's type ::[Int] is more specialized than the right hand side expression's type List[Int] | | If the narrowing is intentional, this can be communicated by adding `: @unchecked` after the expression, | which may result in a MatchError at runtime. | This patch can be rewritten automatically under -rewrite -source 3.2-migration. --- Error: tests/neg/refutable-pattern-binding-messages.scala:16:10 ----------------------------------------------------- -16 | val 1 = 2 // error: pattern type does not match +-- Warning: tests/neg/refutable-pattern-binding-messages.scala:16:10 --------------------------------------------------- +16 | val 1 = 2 // warn: pattern type does not match | ^ | pattern's type (1 : Int) does not match the right hand side expression's type (2 : Int) | diff --git a/tests/neg/refutable-pattern-binding-messages.scala b/tests/neg/refutable-pattern-binding-messages.scala index c6ae043652c2..e71371785d15 100644 --- a/tests/neg/refutable-pattern-binding-messages.scala +++ b/tests/neg/refutable-pattern-binding-messages.scala @@ -1,17 +1,17 @@ -//> using options -Werror + object Test { // refutable extractor object Positive { def unapply(i: Int): Option[Int] = Some(i).filter(_ > 0) } - val Positive(p) = 5 // error: refutable extractor + val Positive(p) = 5 // warn: refutable extractor for Positive(i) <- List(1, 2, 3) do () // error: refutable extractor // more specialized val xs: List[AnyRef] = ??? - val i :: is = List(1, 2, 3) // error: pattern type more specialized + val i :: is = List(1, 2, 3) // warn: pattern type more specialized for ((x: String) <- xs) do () // error: pattern type more specialized // does not match val ys: List[Option[?]] = ??? for none @ None <- ys do () // error: pattern type does not match - val 1 = 2 // error: pattern type does not match + val 1 = 2 // warn: pattern type does not match } diff --git a/tests/neg/rewrite-messages.scala b/tests/neg/rewrite-messages.scala deleted file mode 100644 index 7509682c4baa..000000000000 --- a/tests/neg/rewrite-messages.scala +++ /dev/null @@ -1,8 +0,0 @@ -//> using options -source:future-migration -deprecation -Werror - -import scala.util._ // error - -object Test { - extension (x: Int) def foo(y: Int) = x + y - 2 foo 4 // error -} diff --git a/tests/neg/strict-pattern-bindings-3.2.scala b/tests/neg/strict-pattern-bindings-3.2.scala deleted file mode 100644 index d7db6cd165e4..000000000000 --- a/tests/neg/strict-pattern-bindings-3.2.scala +++ /dev/null @@ -1,37 +0,0 @@ -//> using options -Xfatal-warnings -// These tests should fail under -Xfatal-warnings with source version source version 3.2 or later -import language.`3.2` - -object Test: - // from filtering-fors.scala - val xs: List[AnyRef] = ??? - - for ((x: String) <- xs) do () // error - for (y@ (x: String) <- xs) do () // error - for ((x, y) <- xs) do () // error - - for ((x: String) <- xs if x.isEmpty) do () // error - for ((x: String) <- xs; y = x) do () // error - for ((x: String) <- xs; (y, z) <- xs) do () // error // error - for (case (x: String) <- xs; (y, z) <- xs) do () // error - for ((x: String) <- xs; case (y, z) <- xs) do () // error - - val pairs: List[AnyRef] = List((1, 2), "hello", (3, 4)) - for ((x, y) <- pairs) yield (y, x) // error - - // from unchecked-patterns.scala - val y :: ys = List(1, 2, 3) // error - val (1, c) = (1, 2) // error - val 1 *: cs = 1 *: Tuple() // error - - val (_: Int | _: AnyRef) = ??? : AnyRef // error - - val 1 = 2 // error - - object Positive { def unapply(i: Int): Option[Int] = Some(i).filter(_ > 0) } - object Always1 { def unapply(i: Int): Some[Int] = Some(i) } - object Pair { def unapply(t: (Int, Int)): t.type = t } - object Triple { def unapply(t: (Int, Int, Int)): (Int, Int, Int) = t } - - val Positive(p) = 5 // error - val Some(s1) = Option(1) // error diff --git a/tests/neg/symbolic-packages.scala b/tests/neg/symbolic-packages.scala deleted file mode 100644 index 12719d027b4c..000000000000 --- a/tests/neg/symbolic-packages.scala +++ /dev/null @@ -1,13 +0,0 @@ -//> using options -Xfatal-warnings - -package `with spaces` { // error - class Foo -} - -package +.* { // error // error - class Bar -} - -package object `mixed_*` { // error - class Baz -} diff --git a/tests/neg/warn-value-discard.check b/tests/neg/warn-value-discard.check deleted file mode 100644 index ba43c743709f..000000000000 --- a/tests/neg/warn-value-discard.check +++ /dev/null @@ -1,20 +0,0 @@ --- [E175] Potential Issue Error: tests/neg/warn-value-discard.scala:27:36 ---------------------------------------------- -27 | mutable.Set.empty[String].remove("") // error - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | discarded non-Unit value of type Boolean --- [E175] Potential Issue Error: tests/neg/warn-value-discard.scala:39:41 ---------------------------------------------- -39 | mutable.Set.empty[String].subtractOne("") // error - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | discarded non-Unit value of type scala.collection.mutable.Set[String] --- [E175] Potential Issue Error: tests/neg/warn-value-discard.scala:59:4 ----------------------------------------------- -59 | mutable.Set.empty[String] += "" // error - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | discarded non-Unit value of type scala.collection.mutable.Set[String] --- [E175] Potential Issue Error: tests/neg/warn-value-discard.scala:15:35 ---------------------------------------------- -15 | firstThing().map(_ => secondThing()) // error - | ^^^^^^^^^^^^^ - | discarded non-Unit value of type Either[Failed, Unit] --- [E175] Potential Issue Error: tests/neg/warn-value-discard.scala:18:35 ---------------------------------------------- -18 | firstThing().map(_ => secondThing()) // error - | ^^^^^^^^^^^^^ - | discarded non-Unit value of type Either[Failed, Unit] diff --git a/tests/neg/with-type-operator-future-migration.scala b/tests/neg/with-type-operator-future-migration.scala deleted file mode 100644 index 3ed2e3a8f067..000000000000 --- a/tests/neg/with-type-operator-future-migration.scala +++ /dev/null @@ -1,5 +0,0 @@ -//> using options -Werror - -import scala.language.`future-migration` - -def foo: Int with String = ??? // error diff --git a/tests/warn/14034b.scala b/tests/warn/14034b.scala new file mode 100644 index 000000000000..fdef353f7aca --- /dev/null +++ b/tests/warn/14034b.scala @@ -0,0 +1,15 @@ +//> using options -deprecation + +@deprecated trait Exp +@deprecated val exp = 1 + +def test1 = exp // warn +def test2(a: Exp) = () // warn + +type Foo0 = Exp // warn +type Foo = Option[Exp] // warn +type Bar = Option[exp.type] // warn +type Baz = Exp | Int // warn +type Quux = [X] =>> X match + case Exp => Int // warn +type Quuz[A <: Exp] = Int // warn \ No newline at end of file diff --git a/tests/neg/15981.check b/tests/warn/15981.check similarity index 68% rename from tests/neg/15981.check rename to tests/warn/15981.check index 10745839c566..6cc57d86385f 100644 --- a/tests/neg/15981.check +++ b/tests/warn/15981.check @@ -1,5 +1,5 @@ --- [E092] Pattern Match Error: tests/neg/15981.scala:4:45 -------------------------------------------------------------- -4 | override def equals(any: Any): Boolean = any.isInstanceOf[PosInt] // error +-- [E092] Pattern Match Unchecked Warning: tests/warn/15981.scala:4:45 ------------------------------------------------- +4 | override def equals(any: Any): Boolean = any.isInstanceOf[PosInt] // warn | ^^^ | the type test for PosInt cannot be checked at runtime because it's a local class | diff --git a/tests/neg/15981.scala b/tests/warn/15981.scala similarity index 76% rename from tests/neg/15981.scala rename to tests/warn/15981.scala index 5aba3555c010..a52da28c8462 100644 --- a/tests/neg/15981.scala +++ b/tests/warn/15981.scala @@ -1,6 +1,6 @@ -//> using options -Werror + val _ = locally{ sealed abstract class PosInt(val value: Int) { - override def equals(any: Any): Boolean = any.isInstanceOf[PosInt] // error + override def equals(any: Any): Boolean = any.isInstanceOf[PosInt] // warn } } diff --git a/tests/neg/17284.check b/tests/warn/17284.check similarity index 86% rename from tests/neg/17284.check rename to tests/warn/17284.check index fa248c598311..47df2d21e3a7 100644 --- a/tests/neg/17284.check +++ b/tests/warn/17284.check @@ -1,5 +1,5 @@ --- [E187] Potential Issue Error: tests/neg/17284.scala:4:6 ------------------------------------------------------------- -4 | 451.synchronized {} // error +-- [E187] Potential Issue Warning: tests/warn/17284.scala:4:6 ---------------------------------------------------------- +4 | 451.synchronized {} // warn | ^^^^^^^^^^^^^^^^ | Suspicious synchronized call on boxed class |--------------------------------------------------------------------------------------------------------------------- @@ -8,8 +8,8 @@ | You called the synchronized method on a boxed primitive. This might not be what | you intended. --------------------------------------------------------------------------------------------------------------------- --- [E187] Potential Issue Error: tests/neg/17284.scala:8:4 ------------------------------------------------------------- -8 | x.synchronized {} // error +-- [E187] Potential Issue Warning: tests/warn/17284.scala:8:4 ---------------------------------------------------------- +8 | x.synchronized {} // warn | ^^^^^^^^^^^^^^ | Suspicious synchronized call on boxed class |--------------------------------------------------------------------------------------------------------------------- @@ -18,8 +18,8 @@ | You called the synchronized method on a boxed primitive. This might not be what | you intended. --------------------------------------------------------------------------------------------------------------------- --- [E187] Potential Issue Error: tests/neg/17284.scala:11:7 ------------------------------------------------------------ -11 | true.synchronized {} // error +-- [E187] Potential Issue Warning: tests/warn/17284.scala:11:7 --------------------------------------------------------- +11 | true.synchronized {} // warn | ^^^^^^^^^^^^^^^^^ | Suspicious synchronized call on boxed class |-------------------------------------------------------------------------------------------------------------------- diff --git a/tests/warn/17284.scala b/tests/warn/17284.scala new file mode 100644 index 000000000000..c30e8cb478ec --- /dev/null +++ b/tests/warn/17284.scala @@ -0,0 +1,14 @@ +//> using options -explain + +def test = + 451.synchronized {} // warn + +def test2 = + val x: Integer = 451 + x.synchronized {} // warn + +def test3 = + true.synchronized {} // warn + +def test4 = + true.hashCode() // success \ No newline at end of file diff --git a/tests/warn/1828.scala b/tests/warn/1828.scala new file mode 100644 index 000000000000..2231967a53e0 --- /dev/null +++ b/tests/warn/1828.scala @@ -0,0 +1,11 @@ + + +class Test { + def remove[S](a: S | Int, f: Int => S):S = a match { + case a: S => a // warn + case a: Int => f(a) + } + + val t: Int | String = 5 + val t1 = remove[String](t, _.toString) +} diff --git a/tests/warn/18493.check b/tests/warn/18493.check new file mode 100644 index 000000000000..64f2e2aac735 --- /dev/null +++ b/tests/warn/18493.check @@ -0,0 +1,8 @@ +-- [E030] Match case Unreachable Warning: tests/warn/18493.scala:6:9 --------------------------------------------------- +6 | case "abc" => // warn + | ^^^^^ + | Unreachable case +-- [E030] Match case Unreachable Warning: tests/warn/18493.scala:12:9 -------------------------------------------------- +12 | case "abc" => // warn + | ^^^^^ + | Unreachable case diff --git a/tests/neg/18493.scala b/tests/warn/18493.scala similarity index 68% rename from tests/neg/18493.scala rename to tests/warn/18493.scala index 8dfb3bf923cc..d3ca292a346e 100644 --- a/tests/neg/18493.scala +++ b/tests/warn/18493.scala @@ -1,14 +1,14 @@ -//> using options -Werror + object PartialFunctionNoWarning { // nice warning "abc" match { case "abc" => - case "abc" => // error + case "abc" => // warn } // no warnings val pf: PartialFunction[String, Unit] = { case "abc" => - case "abc" => // error + case "abc" => // warn } } \ No newline at end of file diff --git a/tests/warn/3324b.scala b/tests/warn/3324b.scala new file mode 100644 index 000000000000..9a2011d18012 --- /dev/null +++ b/tests/warn/3324b.scala @@ -0,0 +1,11 @@ + + +class C[T] { + val x: Any = ??? + if (x.isInstanceOf[List[String]]) // warn: unchecked + if (x.isInstanceOf[T]) // warn: unchecked + x match { + case x: List[String] => // warn: unchecked + case x: T => // warn: unchecked + } +} \ No newline at end of file diff --git a/tests/warn/3324f.scala b/tests/warn/3324f.scala new file mode 100644 index 000000000000..86af918b0d5a --- /dev/null +++ b/tests/warn/3324f.scala @@ -0,0 +1,11 @@ + + +trait C[T] +class D[T] + +class Test { + def foo[T](x: C[T]) = x match { + case _: D[T] => // warn + case _: C[Int] => // warn + } +} \ No newline at end of file diff --git a/tests/warn/3324g.scala b/tests/warn/3324g.scala new file mode 100644 index 000000000000..23ff4b3d23f9 --- /dev/null +++ b/tests/warn/3324g.scala @@ -0,0 +1,21 @@ + + +class Test { + trait A[+T] + class B[T] extends A[T] + class C[T] extends B[Any] with A[T] + + def foo[T](c: C[T]): Unit = c match { + case _: B[T] => // warn + } + + def bar[T](b: B[T]): Unit = b match { + case _: A[T] => + } + + def quux[T](a: A[T]): Unit = a match { + case _: B[T] => // warn!! + } + + quux(new C[Int]) +} \ No newline at end of file diff --git a/tests/neg/IsInstanceOfClassTag2.scala b/tests/warn/IsInstanceOfClassTag2.scala similarity index 80% rename from tests/neg/IsInstanceOfClassTag2.scala rename to tests/warn/IsInstanceOfClassTag2.scala index 9d32ee401092..5ca8a8c91765 100644 --- a/tests/neg/IsInstanceOfClassTag2.scala +++ b/tests/warn/IsInstanceOfClassTag2.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + import scala.reflect.TypeTest @@ -11,7 +11,7 @@ object IsInstanceOfClassTag { } def main(args: Array[String]): Unit = { - safeCast[List[String]](List[Int](1)) match { // error + safeCast[List[String]](List[Int](1)) match { // warn case None => case Some(xs) => } @@ -22,3 +22,4 @@ object IsInstanceOfClassTag { } } } + diff --git a/tests/warn/JavaSeqLiteral.scala b/tests/warn/JavaSeqLiteral.scala new file mode 100644 index 000000000000..9652a9fa502c --- /dev/null +++ b/tests/warn/JavaSeqLiteral.scala @@ -0,0 +1,31 @@ + + +object Test1 { + trait Tree[-T] + + class JavaSeqLiteral[T] extends Tree[T] + + trait Type + + class DummyTree extends JavaSeqLiteral[Any] + + def foo1(tree: Tree[Type]) = + tree.isInstanceOf[JavaSeqLiteral[Type]] // warn + + foo1(new DummyTree) +} + +object Test2 { + trait Tree[-T] + + class JavaSeqLiteral[-T] extends Tree[T] + + trait Type + + class DummyTree extends JavaSeqLiteral[Any] + + def foo1(tree: Tree[Type]) = + tree.isInstanceOf[JavaSeqLiteral[Type]] + + foo1(new DummyTree) +} diff --git a/tests/warn/avoid-warn-deprecation.scala b/tests/warn/avoid-warn-deprecation.scala new file mode 100644 index 000000000000..364added5e8a --- /dev/null +++ b/tests/warn/avoid-warn-deprecation.scala @@ -0,0 +1,11 @@ +//> using options -feature + +object A { + @deprecated("use bar instead of this one", "0.2.3") + def foo: Int = 3 +} + +object B { + A.foo +} +// nopos-warn there was 1 deprecation warning; re-run with -deprecation for details \ No newline at end of file diff --git a/tests/warn/conditionalWarnings.scala b/tests/warn/conditionalWarnings.scala new file mode 100644 index 000000000000..5ab63c263abf --- /dev/null +++ b/tests/warn/conditionalWarnings.scala @@ -0,0 +1,15 @@ +//> using options -deprecation + +object Test { + @deprecated def foo = ??? + + given Conversion[String, Int] = _.length + + foo // warn + + val x: Int = "abc" + // OK, since -feature warnings are not enabled. + // The program compiles with final line + // there was 1 feature warning; re-run with -feature for details + // nopos-warn +} \ No newline at end of file diff --git a/tests/neg/convertible.scala b/tests/warn/convertible.scala similarity index 60% rename from tests/neg/convertible.scala rename to tests/warn/convertible.scala index e72de452f41d..c98006ecdc9b 100644 --- a/tests/neg/convertible.scala +++ b/tests/warn/convertible.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings -feature +//> using options -feature import language.experimental.into @@ -11,9 +11,9 @@ object Test: def f(x: Text, y: => Text, zs: Text*) = println(s"${x.str} ${y.str} ${zs.map(_.str).mkString(" ")}") - f("abc", "def") // error // error - f("abc", "def", "xyz", "uvw") // error // error // error // error - f("abc", "def", "xyz", Text("uvw")) // error // error // error + f("abc", "def") // warn // warn + f("abc", "def", "xyz", "uvw") // warn // warn // warn // warn + f("abc", "def", "xyz", Text("uvw")) // warn // warn // warn def g(x: into Text) = println(x.str) @@ -27,5 +27,4 @@ object Test: def h(x: into Text) = val y = h1(x) - y("abc") // error, inference through type variable does not propagate - + y("abc") // warn, inference through type variable does not propagate \ No newline at end of file diff --git a/tests/neg/deprecated-override.scala b/tests/warn/deprecated-override.scala similarity index 52% rename from tests/neg/deprecated-override.scala rename to tests/warn/deprecated-override.scala index b532416c7126..2d0b0ceb4aea 100644 --- a/tests/neg/deprecated-override.scala +++ b/tests/warn/deprecated-override.scala @@ -1,4 +1,4 @@ -//> using options -source future -deprecation -Xfatal-warnings +//> using options -source future -deprecation trait A: def f: Int @@ -7,10 +7,9 @@ class B extends A: @deprecatedOverriding def f = 1 class C extends B: - override def f = 2 // error + override def f = 2 // warn trait D extends A: override def f = 3 -object E extends B, D // error - +object E extends B, D // warn \ No newline at end of file diff --git a/tests/neg/feature-shadowing.scala b/tests/warn/feature-shadowing.scala similarity index 77% rename from tests/neg/feature-shadowing.scala rename to tests/warn/feature-shadowing.scala index 16286d5eea87..301f24b241f7 100644 --- a/tests/neg/feature-shadowing.scala +++ b/tests/warn/feature-shadowing.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings -feature +//> using options -feature import language.implicitConversions given Conversion[Int, String] = _.toString @@ -8,7 +8,7 @@ object a: object b: import language.implicitConversions as _ - val s: String = 2 // error + val s: String = 2 // warn object c: import language.implicitConversions diff --git a/tests/neg/gadt-contradictory-pattern.scala b/tests/warn/gadt-contradictory-pattern.scala similarity index 54% rename from tests/neg/gadt-contradictory-pattern.scala rename to tests/warn/gadt-contradictory-pattern.scala index 6fbd06120a48..5d85b23653db 100644 --- a/tests/neg/gadt-contradictory-pattern.scala +++ b/tests/warn/gadt-contradictory-pattern.scala @@ -1,14 +1,14 @@ -//> using options -Xfatal-warnings -Wimplausible-patterns +//> using options -Wimplausible-patterns object Test { sealed abstract class Foo[T] case object Bar1 extends Foo[Int] case object Bar2 extends Foo[String] case object Bar3 extends Foo[AnyRef] - def fail4[T <: AnyRef](xx: (Foo[T], Foo[T])) = xx match { - case (Bar1, Bar1) => () // error // error + def fail4[T <: AnyRef](xx: (Foo[T], Foo[T])) = xx match { // warn match may not be exhaustive + case (Bar1, Bar1) => () // warn // warn case (Bar2, Bar3) => () case (Bar3, _) => () } -} +} \ No newline at end of file diff --git a/tests/warn/gadt.scala b/tests/warn/gadt.scala new file mode 100644 index 000000000000..9d7b81220284 --- /dev/null +++ b/tests/warn/gadt.scala @@ -0,0 +1,15 @@ + + +class Test { + trait A[+T] + class B[T] extends A[T] + + class C + class D extends C + + def quux(a: A[C]): Unit = a match { + case _: B[C] => // warn + } + + quux(new B[D]) +} diff --git a/tests/warn/html.scala b/tests/warn/html.scala new file mode 100644 index 000000000000..98189c1bf2cb --- /dev/null +++ b/tests/warn/html.scala @@ -0,0 +1,20 @@ + + +object HTML: + type AttrArg = AppliedAttr | Seq[AppliedAttr] + opaque type AppliedAttr = String + opaque type AppliedTag = StringBuilder + + case class Tag(name: String): + def apply(attrs: AttrArg*): AppliedTag = { + val sb = StringBuilder() + sb.append(s"<$name") + attrs.filter(_ != Nil).foreach{ + case s: Seq[AppliedAttr] => + s.foreach(sb.append(" ").append) + case s: Seq[Int] => // warn + case e: AppliedAttr => + sb.append(" ").append(e) + } + sb + } diff --git a/tests/warn/main-functions-nameclash.scala b/tests/warn/main-functions-nameclash.scala new file mode 100644 index 000000000000..bc0fe64379d4 --- /dev/null +++ b/tests/warn/main-functions-nameclash.scala @@ -0,0 +1,5 @@ + + +object foo { + @main def foo(x: Int) = () // warn: class foo and object foo produce classes that overwrite one another +} diff --git a/tests/neg/manifest-summoning-b.check b/tests/warn/manifest-summoning-b.check similarity index 73% rename from tests/neg/manifest-summoning-b.check rename to tests/warn/manifest-summoning-b.check index bb63eebb555f..590b27ddbd98 100644 --- a/tests/neg/manifest-summoning-b.check +++ b/tests/warn/manifest-summoning-b.check @@ -1,12 +1,12 @@ --- Error: tests/neg/manifest-summoning-b.scala:3:34 -------------------------------------------------------------------- -3 |val foo = manifest[List[? <: Int]] // error +-- Deprecation Warning: tests/warn/manifest-summoning-b.scala:3:34 ----------------------------------------------------- +3 |val foo = manifest[List[? <: Int]] // warn | ^ | Compiler synthesis of Manifest and OptManifest is deprecated, instead | replace with the type `scala.reflect.ClassTag[List[? <: Int]]`. | Alternatively, consider using the new metaprogramming features of Scala 3, | see https://docs.scala-lang.org/scala3/reference/metaprogramming.html --- Error: tests/neg/manifest-summoning-b.scala:4:41 -------------------------------------------------------------------- -4 |val bar = optManifest[Array[? <: String]] // error +-- Deprecation Warning: tests/warn/manifest-summoning-b.scala:4:41 ----------------------------------------------------- +4 |val bar = optManifest[Array[? <: String]] // warn | ^ | Compiler synthesis of Manifest and OptManifest is deprecated, instead | replace with the type `scala.reflect.ClassTag[Array[? <: String]]`. diff --git a/tests/warn/manifest-summoning-b.scala b/tests/warn/manifest-summoning-b.scala new file mode 100644 index 000000000000..18ddec1250b5 --- /dev/null +++ b/tests/warn/manifest-summoning-b.scala @@ -0,0 +1,4 @@ +//> using options -deprecation + +val foo = manifest[List[? <: Int]] // warn +val bar = optManifest[Array[? <: String]] // warn \ No newline at end of file diff --git a/tests/warn/matchable.scala b/tests/warn/matchable.scala new file mode 100644 index 000000000000..8adcdcf1c90a --- /dev/null +++ b/tests/warn/matchable.scala @@ -0,0 +1,28 @@ +//> using options -source future + +def foo[T](x: T): Matchable = + println(x.getClass()) // ok + println(x.isInstanceOf[Int]) // ok + x match + case x: Int => // warn: should not be scrutinized + println("int") + x + case x: String => // warn: should not be scrutinized + println("string") + x + List(x) match + case (x: Int) :: Nil => // warn: should not be scrutinized + println("int") + x + case List(x: String) => // warn: should not be scrutinized + println("string") + x + case List(y :: Nil) => // warn: should not be scrutinized + y :: Nil + case _ => + x // warn: should not be scrutinized + +@main def Test = + val x: Matchable = foo(1) + val y: Matchable = foo("hello") + assert(x != y) \ No newline at end of file diff --git a/tests/neg/newline-braces.scala b/tests/warn/newline-braces.scala similarity index 55% rename from tests/neg/newline-braces.scala rename to tests/warn/newline-braces.scala index afe7731f3095..9ec2961ee30d 100644 --- a/tests/neg/newline-braces.scala +++ b/tests/warn/newline-braces.scala @@ -1,8 +1,9 @@ -//> using options -source 3.0-migration -Xfatal-warnings +//> using options -source 3.0-migration def f: List[Int] = { List(1, 2, 3).map // no newline inserted here in Scala-2 compat mode - { x => // error (migration) + { x => // warn (migration) x + 1 } } + diff --git a/tests/neg/nonunit-statement.scala b/tests/warn/nonunit-statement.scala similarity index 80% rename from tests/neg/nonunit-statement.scala rename to tests/warn/nonunit-statement.scala index 94346031077c..f90deb647d6e 100644 --- a/tests/neg/nonunit-statement.scala +++ b/tests/warn/nonunit-statement.scala @@ -1,4 +1,5 @@ -//> using options -Xfatal-warnings -Wnonunit-statement -Wvalue-discard -source:3.3 +//> using options -Wnonunit-statement -Wvalue-discard -source:3.3 + import collection.ArrayOps import collection.mutable.{ArrayBuilder, LinkedHashSet, ListBuffer} import concurrent._ @@ -9,38 +10,38 @@ class C { def c = { def improved = Future(42) def stale = Future(27) - improved // error + improved // warn stale } } class D { def d = { class E - new E().toString // error + new E().toString // warn new E().toString * 2 } } class F { import ExecutionContext.Implicits._ - Future(42) // error + Future(42) // warn } // unused template expression uses synthetic method of class case class K(s: String) { - copy() // error + copy() // warn } // mutations returning this are ok class Mutate { val b = ListBuffer.empty[Int] b += 42 // nowarn, returns this.type val xs = List(42) - 27 +: xs // error + 27 +: xs // warn def f(x: Int): this.type = this def g(): Unit = f(42) // nowarn } // some uninteresting expressions may warn for other reasons class WhoCares { - null // error for purity + null // warn for purity ??? // nowarn for impurity } // explicit Unit ascription to opt out of warning, even for funky applies @@ -50,15 +51,15 @@ class Absolution { // Future(42): Unit // nowarn { F(42)(ctx) }: Unit where annot is on F(42) // f(42): Unit // nowarn } -// warn uni-branched unless user disables it with -Wnonunit-if:false + class Boxed[A](a: A) { def isEmpty = false def foreach[U](f: A => U): Unit = - if (!isEmpty) f(a) // error (if) + if (!isEmpty) f(a) // warn (if) def forall(f: A => Boolean): Unit = if (!isEmpty) { println(".") - f(a) // error (if) + f(a) // warn (if) } def take(p: A => Boolean): Option[A] = { while (isEmpty || !p(a)) () @@ -69,20 +70,20 @@ class Unibranch[A, B] { def runWith[U](action: B => U): A => Boolean = { x => val z = null.asInstanceOf[B] val fellback = false - if (!fellback) action(z) // error (if) + if (!fellback) action(z) // warn (if) !fellback } def f(i: Int): Int = { def g = 17 if (i < 42) { - g // error block statement + g // warn block statement println("uh oh") - g // error (if) + g // warn (if) } while (i < 42) { - g // error + g // warn println("uh oh") - g // error + g // warn } 42 } @@ -92,7 +93,7 @@ class Dibranch { def j: Int = ??? def f(b: Boolean): Int = { // if-expr might have an uninteresting LUB - if (b) { // error, at least one branch looks interesting + if (b) { // warn, at least one branch looks interesting println("true") i } @@ -112,7 +113,7 @@ class Next[A] { class Setting[A] { def set = LinkedHashSet.empty[A] def f(a: A): Unit = { - set += a // error because cannot know whether the `set` was supposed to be consumed or assigned + set += a // warn because cannot know whether the `set` was supposed to be consumed or assigned println(set) } } @@ -122,27 +123,27 @@ class Strung { def iterator = Iterator.empty[String] def addString(b: StringBuilder, start: String, sep: String, end: String): StringBuilder = { val jsb = b.underlying - if (start.length != 0) jsb.append(start) // error (value-discard) + if (start.length != 0) jsb.append(start) // warn (value-discard) val it = iterator if (it.hasNext) { jsb.append(it.next()) while (it.hasNext) { jsb.append(sep) // nowarn (java) - jsb.append(it.next()) // error (value-discard) + jsb.append(it.next()) // warn (value-discard) } } - if (end.length != 0) jsb.append(end) // error (value-discard) + if (end.length != 0) jsb.append(end) // warn (value-discard) b } def f(b: java.lang.StringBuilder, it: Iterator[String]): String = { while (it.hasNext) { b.append("\n") // nowarn (java) - b.append(it.next()) // error (value-discard) + b.append(it.next()) // warn (value-discard) } b.toString } def g(b: java.lang.StringBuilder, it: Iterator[String]): String = { - while (it.hasNext) it.next() // error + while (it.hasNext) it.next() // warn b.toString } } @@ -195,4 +196,4 @@ class Depends { f(d) () } -} +} \ No newline at end of file diff --git a/tests/warn/old-syntax.scala b/tests/warn/old-syntax.scala new file mode 100644 index 000000000000..d584e3692a0a --- /dev/null +++ b/tests/warn/old-syntax.scala @@ -0,0 +1,5 @@ +//> using options -deprecation + +val f = (x: Int) ⇒ x + 1 // warn + +val list = for (n ← List(42)) yield n + 1 // warn \ No newline at end of file diff --git a/tests/neg/opaque-match.scala b/tests/warn/opaque-match.scala similarity index 63% rename from tests/neg/opaque-match.scala rename to tests/warn/opaque-match.scala index 59d0836fb2a3..453d525bac2c 100644 --- a/tests/neg/opaque-match.scala +++ b/tests/warn/opaque-match.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + case class C() @@ -12,17 +12,13 @@ def Test[T] = O.x match case _: C => ??? // ok C() match - case _: O.T => ??? // error + case _: O.T => ??? // warn C() match - case _: T => ??? // error + case _: T => ??? // warn (??? : Any) match - case _: List[O.T] => ??? // error + case _: List[O.T] => ??? // warn (??? : Any) match case _: List[O.T @unchecked] => ??? // OK (??? : Any) match - case _: List[T] => ??? // error - - - - + case _: List[T] => ??? // warn \ No newline at end of file diff --git a/tests/warn/or-type-trees.scala b/tests/warn/or-type-trees.scala new file mode 100644 index 000000000000..0e8569576796 --- /dev/null +++ b/tests/warn/or-type-trees.scala @@ -0,0 +1,40 @@ + + +object Test1 { + trait Tree + trait Context + + def foo1(myTree: Tree | (Context => Tree)) = + println(myTree.isInstanceOf[Tree]) + + def foo2(myTree: Tree | (Context => Tree)) = + myTree match + case treeFn: (Context => Tree) => // warn + case _ => + + def foo3(myTree: Tree | (Context => Tree)) = + myTree match + case treeFn: (? => ?) => // ok + case _ => +} + +object Test2 { + trait Tree[-T] + trait Context + + trait Type + + def foo1(myTree: Tree[Type] | (Context => Tree[Type])) = + println(myTree.isInstanceOf[Tree[Type]]) // warn + /* class DummyTree extends Tree[Nothing] with (Context => Tree[Type]) */ + + def foo2(myTree: Tree[Type] | (Context => Tree[Type])) = + myTree match + case treeFn: (Context => Tree[Type]) => // warn + case _ => + + def foo3(myTree: Tree[Type] | (Context => Tree[Type])) = + myTree match + case treeFn: (? => ?) => // ok + case _ => +} \ No newline at end of file diff --git a/tests/warn/ovlazy.scala b/tests/warn/ovlazy.scala new file mode 100644 index 000000000000..1dfa284a00c9 --- /dev/null +++ b/tests/warn/ovlazy.scala @@ -0,0 +1,9 @@ +//> using options -source 3.0-migration + +class A { + val x: Int = 1 +} +class B extends A { + override lazy val x: Int = 2 // warn +} + diff --git a/tests/neg/private-this-3.4.check b/tests/warn/private-this-3.4.check similarity index 76% rename from tests/neg/private-this-3.4.check rename to tests/warn/private-this-3.4.check index 8ee55d2b5f29..2ba2fea549d1 100644 --- a/tests/neg/private-this-3.4.check +++ b/tests/warn/private-this-3.4.check @@ -1,12 +1,12 @@ --- Error: tests/neg/private-this-3.4.scala:6:16 ------------------------------------------------------------------------ -6 | private[this] def foo: Int = ??? // error: migration warning +-- Warning: tests/warn/private-this-3.4.scala:4:16 --------------------------------------------------------------------- +4 | private[this] def foo: Int = ??? // warn: migration warning | ^ | Ignoring [this] qualifier. | This syntax will be deprecated in the future; it should be dropped. | See: https://docs.scala-lang.org/scala3/reference/dropped-features/this-qualifier.html | This construct can be rewritten automatically under -rewrite -source 3.4-migration. --- Error: tests/neg/private-this-3.4.scala:7:18 ------------------------------------------------------------------------ -7 | protected[this] def bar: Int = ??? // error: migration warning +-- Warning: tests/warn/private-this-3.4.scala:5:18 --------------------------------------------------------------------- +5 | protected[this] def bar: Int = ??? // warn: migration warning | ^ | Ignoring [this] qualifier. | This syntax will be deprecated in the future; it should be dropped. diff --git a/tests/warn/private-this-3.4.scala b/tests/warn/private-this-3.4.scala new file mode 100644 index 000000000000..1270eba116bc --- /dev/null +++ b/tests/warn/private-this-3.4.scala @@ -0,0 +1,5 @@ +import scala.language.`3.4` + +class Foo: + private[this] def foo: Int = ??? // warn: migration warning + protected[this] def bar: Int = ??? // warn: migration warning diff --git a/tests/warn/private-this-future-migration.scala b/tests/warn/private-this-future-migration.scala new file mode 100644 index 000000000000..d719187e534a --- /dev/null +++ b/tests/warn/private-this-future-migration.scala @@ -0,0 +1,5 @@ +import scala.language.`future-migration` + +class Foo: + private[this] def foo: Int = ??? // warn: migration warning + protected[this] def bar: Int = ??? // warn: migration warning diff --git a/tests/warn/quote-simple-hole.scala b/tests/warn/quote-simple-hole.scala new file mode 100644 index 000000000000..f23d2c0535c4 --- /dev/null +++ b/tests/warn/quote-simple-hole.scala @@ -0,0 +1,17 @@ + + +import scala.quoted.Quotes + +def test(using Quotes) = { + val x = '{0} + val y = '{ // warn: Canceled splice directly inside a quote. '{ ${ XYZ } } is equivalent to XYZ. + $x + } + val z = '{ + val a = ${ // warn: Canceled quote directly inside a splice. ${ '{ XYZ } } is equivalent to XYZ. + '{ + $y + } + } + } +} \ No newline at end of file diff --git a/tests/warn/refined-types.scala b/tests/warn/refined-types.scala new file mode 100644 index 000000000000..1ef0f84c00d4 --- /dev/null +++ b/tests/warn/refined-types.scala @@ -0,0 +1,24 @@ + + +class A +class B extends A +type AA = A { type T = Int } +type BA = B { type T = Int } +type AL = A { type T >: Int } +type BL = B { type T >: Int } +type AU = A { type T <: Int } +type BU = B { type T <: Int } + +def aa(x: AA) = x.isInstanceOf[BA] // was: the type test for BA cannot be checked at runtime +def al(x: AL) = x.isInstanceOf[BL] // was: the type test for BL cannot be checked at runtime +def au(x: AU) = x.isInstanceOf[BU] // was: the type test for BU cannot be checked at runtime + +// an alias leaves nothing unchecked when type testing against one bound: +def bl(x: AA) = x.isInstanceOf[BL] // was: the type test for BL cannot be checked at runtime +def bu(x: AA) = x.isInstanceOf[BU] // was: the type test for BU cannot be checked at runtime + +// but static knowledge of only one bound makes checking against an alias unchecked: +def al_ba(x: AL) = x.isInstanceOf[BA] // warn: the type test for BA cannot be checked at runtime +def au_ba(x: AU) = x.isInstanceOf[BA] // warn: the type test for BA cannot be checked at runtime +def al_bu(x: AL) = x.isInstanceOf[BU] // warn: the type test for BU cannot be checked at runtime +def au_bl(x: AU) = x.isInstanceOf[BL] // warn: the type test for BL cannot be checked at runtime \ No newline at end of file diff --git a/tests/warn/refinements-this.scala b/tests/warn/refinements-this.scala new file mode 100644 index 000000000000..3e4c64cf1e59 --- /dev/null +++ b/tests/warn/refinements-this.scala @@ -0,0 +1,6 @@ + + +class Outer: + type X = { type O = Outer.this.type } // ok + type Y = { type O = this.type } // warn + diff --git a/tests/neg/rewrite-messages.check b/tests/warn/rewrite-messages.check similarity index 76% rename from tests/neg/rewrite-messages.check rename to tests/warn/rewrite-messages.check index b062ab2bc732..d7147239cded 100644 --- a/tests/neg/rewrite-messages.check +++ b/tests/warn/rewrite-messages.check @@ -1,10 +1,10 @@ --- Error: tests/neg/rewrite-messages.scala:3:18 ------------------------------------------------------------------------ -3 |import scala.util._ // error +-- Migration Warning: tests/warn/rewrite-messages.scala:3:18 ----------------------------------------------------------- +3 |import scala.util._ // warn | ^ | `_` is no longer supported for a wildcard import; use `*` instead | This construct can be rewritten automatically under -rewrite -source future-migration. --- Error: tests/neg/rewrite-messages.scala:7:4 ------------------------------------------------------------------------- -7 | 2 foo 4 // error +-- Migration Warning: tests/warn/rewrite-messages.scala:7:4 ------------------------------------------------------------ +7 | 2 foo 4 // warn | ^^^ | Alphanumeric method foo is not declared infix; it should not be used as infix operator. | Instead, use method syntax .foo(...) or backticked identifier `foo`. diff --git a/tests/warn/rewrite-messages.scala b/tests/warn/rewrite-messages.scala new file mode 100644 index 000000000000..88166f8e8ac2 --- /dev/null +++ b/tests/warn/rewrite-messages.scala @@ -0,0 +1,8 @@ +//> using options -source:future-migration -deprecation + +import scala.util._ // warn + +object Test { + extension (x: Int) def foo(y: Int) = x + y + 2 foo 4 // warn +} \ No newline at end of file diff --git a/tests/neg/i15503-scala2/scala2-t11681.scala b/tests/warn/scala2-t11681.scala similarity index 90% rename from tests/neg/i15503-scala2/scala2-t11681.scala rename to tests/warn/scala2-t11681.scala index 2436668e0c9c..ae2187181ceb 100644 --- a/tests/neg/i15503-scala2/scala2-t11681.scala +++ b/tests/warn/scala2-t11681.scala @@ -1,5 +1,5 @@ -//> using options -Xfatal-warnings -Wunused:params -// +//> using options -Wunused:params + import Answers._ @@ -10,7 +10,7 @@ trait InterFace { trait BadAPI extends InterFace { private def f(a: Int, - b: String, // error + b: String, // warn c: Double): Int = { println(c) a @@ -47,10 +47,9 @@ trait BadAPI extends InterFace { // mustn't alter warnings in super trait PoorClient extends BadAPI { override def meth(x: Int) = ??? // OK - override def f(a: Int, b: String, c: Double): Int = a + b.toInt + c.toInt } -class Unusing(u: Int) { // error +class Unusing(u: Int) { // warn def f = ??? } @@ -107,4 +106,4 @@ object Answers { def answer: Int = 42 } -val a$1 = 2 \ No newline at end of file +val a$1 = 2 diff --git a/tests/warn/strict-pattern-bindings-3.2.scala b/tests/warn/strict-pattern-bindings-3.2.scala new file mode 100644 index 000000000000..e4df8e770a01 --- /dev/null +++ b/tests/warn/strict-pattern-bindings-3.2.scala @@ -0,0 +1,37 @@ + +// These tests should fail under -Xfatal-warnings with source version source version 3.2 or later +import language.`3.2` + +object Test: + // from filtering-fors.scala + val xs: List[AnyRef] = ??? + + for ((x: String) <- xs) do () // warn + for (y@ (x: String) <- xs) do () // warn + for ((x, y) <- xs) do () // warn + + for ((x: String) <- xs if x.isEmpty) do () // warn + for ((x: String) <- xs; y = x) do () // warn + for ((x: String) <- xs; (y, z) <- xs) do () // warn // warn + for (case (x: String) <- xs; (y, z) <- xs) do () // warn + for ((x: String) <- xs; case (y, z) <- xs) do () // warn + + val pairs: List[AnyRef] = List((1, 2), "hello", (3, 4)) + for ((x, y) <- pairs) yield (y, x) // warn + + // from unchecked-patterns.scala + val y :: ys = List(1, 2, 3) // warn + val (1, c) = (1, 2) // warn + val 1 *: cs = 1 *: Tuple() // warn + + val (_: Int | _: AnyRef) = ??? : AnyRef // warn + + val 1 = 2 // warn + + object Positive { def unapply(i: Int): Option[Int] = Some(i).filter(_ > 0) } + object Always1 { def unapply(i: Int): Some[Int] = Some(i) } + object Pair { def unapply(t: (Int, Int)): t.type = t } + object Triple { def unapply(t: (Int, Int, Int)): (Int, Int, Int) = t } + + val Positive(p) = 5 // warn + val Some(s1) = Option(1) // warn \ No newline at end of file diff --git a/tests/neg/supertraits-b.scala b/tests/warn/supertraits-b.scala similarity index 69% rename from tests/neg/supertraits-b.scala rename to tests/warn/supertraits-b.scala index 78854537974e..b36fcb5634b7 100644 --- a/tests/neg/supertraits-b.scala +++ b/tests/warn/supertraits-b.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + transparent sealed trait TA transparent sealed trait TB @@ -16,20 +16,20 @@ object Test: choose0(a, b) match case _: TA => ??? - case _: TB => ??? // error: unreachable + case _: TB => ??? // warn: unreachable choose1(a, b) match case _: TA => ??? - case _: TB => ??? // error: unreachable + case _: TB => ??? // warn: unreachable choose2(a, b) match case _: TB => ??? - case _: TA => ??? // error: unreachable + case _: TA => ??? // warn: unreachable choose3(a, b) match case _: Product => ??? - case _: TA => ??? // error: unreachable + case _: TA => ??? // warn: unreachable choose4(a, b) match case _: (TA & TB) => ??? - case _: Product => ??? // error: unreachable \ No newline at end of file + case _: Product => ??? // warn: unreachable \ No newline at end of file diff --git a/tests/neg/switches.scala b/tests/warn/switches.scala similarity index 77% rename from tests/neg/switches.scala rename to tests/warn/switches.scala index d405f8185706..9b45e3ed0d51 100644 --- a/tests/neg/switches.scala +++ b/tests/warn/switches.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + import scala.annotation.switch @@ -38,7 +38,7 @@ object Main { // multiple annotations are processed correctly // thinks a val in an object is constant... so naive - def fail1(c: Char) = (c: @switch @unchecked) match { // error: Could not emit switch for @switch annotated match + def fail1(c: Char) = (c: @switch @unchecked) match { // warn: Could not emit switch for @switch annotated match case 'A' => true case 'B' => true case Other.C1 => true @@ -46,7 +46,7 @@ object Main { } // more naivete - def fail2(c: Char) = (c: @unchecked @switch) match { // error: Could not emit switch for @switch annotated match + def fail2(c: Char) = (c: @unchecked @switch) match { // warn: Could not emit switch for @switch annotated match case 'A' => true case 'B' => true case Other.C3 => true @@ -69,12 +69,12 @@ object Main { case _ => -1 } - def fail3(x: Any) = (x: @switch) match { // error: Could not emit switch for @switch annotated match + def fail3(x: Any) = (x: @switch) match { // warn: Could not emit switch for @switch annotated match case 1 | 2 | 3 => true case _ => false } - def fail4(x: AnyVal) = (x: @switch) match { // error: Could not emit switch for @switch annotated match + def fail4(x: AnyVal) = (x: @switch) match { // warn: Could not emit switch for @switch annotated match case 1 | 2 | 3 => true case _ => false } @@ -82,7 +82,7 @@ object Main { case class IntAnyVal(x: Int) extends AnyVal val Ten = IntAnyVal(10) - def fail5(x: IntAnyVal) = (x: @switch) match { // error: Could not emit switch for @switch annotated match + def fail5(x: IntAnyVal) = (x: @switch) match { // warn: Could not emit switch for @switch annotated match case IntAnyVal(1) => 0 case Ten => 1 case IntAnyVal(100) => 2 @@ -92,11 +92,11 @@ object Main { // the generated lookupswitch covers only a subset of the cases final val One = IntAnyVal(1) - def fail6(x: IntAnyVal) = (x: @switch) match { // error: Could not emit switch for @switch annotated match + def fail6(x: IntAnyVal) = (x: @switch) match { // warn: Could not emit switch for @switch annotated match case One => 0 case IntAnyVal(10) => 1 case IntAnyVal(100) => 2 case IntAnyVal(1000) => 3 case IntAnyVal(10000) => 4 } -} +} \ No newline at end of file diff --git a/tests/neg/symbolic-packages.check b/tests/warn/symbolic-packages.check similarity index 65% rename from tests/neg/symbolic-packages.check rename to tests/warn/symbolic-packages.check index 8e9b7e114829..c1d56f67eba7 100644 --- a/tests/neg/symbolic-packages.check +++ b/tests/warn/symbolic-packages.check @@ -1,16 +1,16 @@ --- Error: tests/neg/symbolic-packages.scala:3:8 ------------------------------------------------------------------------ -3 |package `with spaces` { // error +-- Warning: tests/warn/symbolic-packages.scala:3:8 --------------------------------------------------------------------- +3 |package `with spaces` { // warn | ^^^^^^^^^^^^^ | The package name `with spaces` will be encoded on the classpath, and can lead to undefined behaviour. --- Error: tests/neg/symbolic-packages.scala:7:10 ----------------------------------------------------------------------- -7 |package +.* { // error // error +-- Warning: tests/warn/symbolic-packages.scala:7:10 -------------------------------------------------------------------- +7 |package +.* { // warn // warn | ^ | The package name `*` will be encoded on the classpath, and can lead to undefined behaviour. --- Error: tests/neg/symbolic-packages.scala:7:8 ------------------------------------------------------------------------ -7 |package +.* { // error // error +-- Warning: tests/warn/symbolic-packages.scala:7:8 --------------------------------------------------------------------- +7 |package +.* { // warn // warn | ^ | The package name `+` will be encoded on the classpath, and can lead to undefined behaviour. --- Error: tests/neg/symbolic-packages.scala:11:16 ---------------------------------------------------------------------- -11 |package object `mixed_*` { // error +-- Warning: tests/warn/symbolic-packages.scala:11:16 ------------------------------------------------------------------- +11 |package object `mixed_*` { // warn | ^^^^^^^ | The package name `mixed_*` will be encoded on the classpath, and can lead to undefined behaviour. diff --git a/tests/warn/symbolic-packages.scala b/tests/warn/symbolic-packages.scala new file mode 100644 index 000000000000..6e0ef04da6bb --- /dev/null +++ b/tests/warn/symbolic-packages.scala @@ -0,0 +1,13 @@ + + +package `with spaces` { // warn + class Foo +} + +package +.* { // warn // warn + class Bar +} + +package object `mixed_*` { // warn + class Baz +} \ No newline at end of file diff --git a/tests/warn/t2755.scala b/tests/warn/t2755.scala new file mode 100644 index 000000000000..1aeb06d237d1 --- /dev/null +++ b/tests/warn/t2755.scala @@ -0,0 +1,60 @@ + + +// Test cases: the only place we can cut and paste without crying +// ourself to sleep. +object Test { + def f1(a: Any) = a match { + case x: Array[Int] => x(0) + case x: Array[Double] => 2 + case x: Array[Float] => x.sum.toInt + case x: Array[String] => x.size + case x: Array[AnyRef] => 5 + case x: Array[?] => 6 + case _ => 7 + } + def f2(a: Array[?]) = a match { + case x: Array[Int] => x(0) + case x: Array[Double] => 2 + case x: Array[Float] => x.sum.toInt + case x: Array[String] => x.size + case x: Array[AnyRef] => 5 + case x: Array[?] => 6 + case _ => 7 // warn: only null is matched + } + def f3[T](a: Array[T]) = a match { + case x: Array[Int] => x(0) + case x: Array[Double] => 2 + case x: Array[Float] => x.sum.toInt + case x: Array[String] => x.size + case x: Array[AnyRef] => 5 + case x: Array[?] => 6 + case _ => 7 // warn: only null is matched + } + + + def main(args: Array[String]): Unit = { + println(f1(Array(1, 2, 3))) + println(f1(Array(1.0, -2.0, 3.0, 1.0))) + println(f1(Array(1.0f, 2.0f, 3.0f, -3.0f))) + println(f1((1 to 4).toArray map (_.toString))) + println(f1(new Array[Any](10))) // should match as Array[AnyRef] + println(f1(Array(1L))) + println(f1(null)) + + println(f2(Array(1, 2, 3))) + println(f2(Array(1.0, -2.0, 3.0, 1.0))) + println(f2(Array(1.0f, 2.0f, 3.0f, -3.0f))) + println(f2((1 to 4).toArray map (_.toString))) + println(f2(new Array[Any](10))) // should match as Array[AnyRef] + println(f2(Array(1L))) + println(f2(null)) + + println(f3(Array(1, 2, 3))) + println(f3(Array(1.0, -2.0, 3.0, 1.0))) + println(f3(Array(1.0f, 2.0f, 3.0f, -3.0f))) + println(f3((1 to 4).toArray map (_.toString))) + println(f3(new Array[Any](10))) // should match as Array[AnyRef] + println(f3(Array(1L))) + println(f3(null)) + } +} \ No newline at end of file diff --git a/tests/neg/t3235-minimal.check b/tests/warn/t3235-minimal.check similarity index 75% rename from tests/neg/t3235-minimal.check rename to tests/warn/t3235-minimal.check index 83c287f85bc0..dcd28466f729 100644 --- a/tests/neg/t3235-minimal.check +++ b/tests/warn/t3235-minimal.check @@ -1,16 +1,16 @@ --- Error: tests/neg/t3235-minimal.scala:5:21 --------------------------------------------------------------------------- -5 | assert(123456789.round == 123456789) // error +-- Deprecation Warning: tests/warn/t3235-minimal.scala:5:21 ------------------------------------------------------------ +5 | assert(123456789.round == 123456789) // warn | ^^^^^^^^^^^^^^^ |method round in class RichInt is deprecated since 2.11.0: this is an integer type; there is no reason to round it. Perhaps you meant to call this on a floating-point value? --- Error: tests/neg/t3235-minimal.scala:6:16 --------------------------------------------------------------------------- -6 | assert(math.round(123456789) == 123456789) // error +-- Deprecation Warning: tests/warn/t3235-minimal.scala:6:16 ------------------------------------------------------------ +6 | assert(math.round(123456789) == 123456789) // warn | ^^^^^^^^^^ |method round in package scala.math is deprecated since 2.11.0: This is an integer type; there is no reason to round it. Perhaps you meant to call this with a floating-point value? --- Error: tests/neg/t3235-minimal.scala:7:32 --------------------------------------------------------------------------- -7 | assert(1234567890123456789L.round == 1234567890123456789L) // error +-- Deprecation Warning: tests/warn/t3235-minimal.scala:7:32 ------------------------------------------------------------ +7 | assert(1234567890123456789L.round == 1234567890123456789L) // warn | ^^^^^^^^^^^^^^^^^^^^^^^^^^ |method round in class RichLong is deprecated since 2.11.0: this is an integer type; there is no reason to round it. Perhaps you meant to call this on a floating-point value? --- Error: tests/neg/t3235-minimal.scala:8:16 --------------------------------------------------------------------------- -8 | assert(math.round(1234567890123456789L) == 1234567890123456789L) // error +-- Deprecation Warning: tests/warn/t3235-minimal.scala:8:16 ------------------------------------------------------------ +8 | assert(math.round(1234567890123456789L) == 1234567890123456789L) // warn | ^^^^^^^^^^ |method round in package scala.math is deprecated since 2.11.0: This is an integer type; there is no reason to round it. Perhaps you meant to call this with a floating-point value? diff --git a/tests/neg/t3235-minimal.scala b/tests/warn/t3235-minimal.scala similarity index 51% rename from tests/neg/t3235-minimal.scala rename to tests/warn/t3235-minimal.scala index f65ee13f87f5..22e6da9f31a0 100644 --- a/tests/neg/t3235-minimal.scala +++ b/tests/warn/t3235-minimal.scala @@ -1,10 +1,10 @@ -//> using options -Xfatal-warnings -deprecation +//> using options -deprecation object Test { def main(args: Array[String]): Unit = { - assert(123456789.round == 123456789) // error - assert(math.round(123456789) == 123456789) // error - assert(1234567890123456789L.round == 1234567890123456789L) // error - assert(math.round(1234567890123456789L) == 1234567890123456789L) // error + assert(123456789.round == 123456789) // warn + assert(math.round(123456789) == 123456789) // warn + assert(1234567890123456789L.round == 1234567890123456789L) // warn + assert(math.round(1234567890123456789L) == 1234567890123456789L) // warn } -} +} \ No newline at end of file diff --git a/tests/neg/t5830.scala b/tests/warn/t5830.scala similarity index 63% rename from tests/neg/t5830.scala rename to tests/warn/t5830.scala index 947b7bac4a22..41cdfb1059a7 100644 --- a/tests/neg/t5830.scala +++ b/tests/warn/t5830.scala @@ -1,11 +1,11 @@ -//> using options -Xfatal-warnings + import scala.annotation.switch class Test { def unreachable(ch: Char) = (ch: @switch) match { case 'a' => println("b") // ok - case 'a' => println("b") // error: unreachable case + case 'a' => println("b") // warn: unreachable case case 'c' => } } diff --git a/tests/warn/type-lambda.scala b/tests/warn/type-lambda.scala new file mode 100644 index 000000000000..788647496a4f --- /dev/null +++ b/tests/warn/type-lambda.scala @@ -0,0 +1,16 @@ + + +trait A[T] +trait B[T] extends A[T] + +object Test { + def foo(x: ([X] =>> A[X])[Any]) = x match { + case x: ([X] =>> B[X])[Any] => + case _ => + } + + def bar(x: ([X] =>> A[X])[Any]) = x match { + case x: ([X] =>> B[Nothing])[Any] => // warn + case _ => + } +} diff --git a/tests/neg/type-test-paths-2.scala b/tests/warn/type-test-paths-2.scala similarity index 61% rename from tests/neg/type-test-paths-2.scala rename to tests/warn/type-test-paths-2.scala index 4bba2f87416e..79b22fa70049 100644 --- a/tests/neg/type-test-paths-2.scala +++ b/tests/warn/type-test-paths-2.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + import scala.reflect.TypeTest @@ -29,15 +29,15 @@ object Test { val r2: R = RI r1.n match { - case n: r2.Nat => // error: the type test for Test.r2.Nat cannot be checked at runtime - case n: r1.Idx => // error: the type test for Test.r1.Idx cannot be checked at runtime + case n: r2.Nat => // warn: the type test for Test.r2.Nat cannot be checked at runtime + case n: r1.Idx => // warn: the type test for Test.r1.Idx cannot be checked at runtime case n: r1.Succ => // Ok case n: r1.Nat => // Ok } r1.one match { - case n: r2.Nat => // error: the type test for Test.r2.Nat cannot be checked at runtime - case n: r1.Idx => // error: the type test for Test.r1.Idx cannot be checked at runtime + case n: r2.Nat => // warn: the type test for Test.r2.Nat cannot be checked at runtime + case n: r1.Idx => // warn: the type test for Test.r1.Idx cannot be checked at runtime case n: r1.Nat => // Ok } -} +} \ No newline at end of file diff --git a/tests/neg/type-test-paths.scala b/tests/warn/type-test-paths.scala similarity index 88% rename from tests/neg/type-test-paths.scala rename to tests/warn/type-test-paths.scala index 324ed43ba7fa..03501cfd5957 100644 --- a/tests/neg/type-test-paths.scala +++ b/tests/warn/type-test-paths.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + import scala.reflect.TypeTest @@ -8,7 +8,7 @@ object Test { val p2: T = T1 (p1.y: p1.X) match { - case x: p2.Y => // error: unchecked + case x: p2.Y => // warn: unchecked case x: p1.Y => case _ => } diff --git a/tests/neg/type-test-syntesize-b.scala b/tests/warn/type-test-syntesize-b.scala similarity index 74% rename from tests/neg/type-test-syntesize-b.scala rename to tests/warn/type-test-syntesize-b.scala index b5402eb92c66..ba8ffb8318b7 100644 --- a/tests/neg/type-test-syntesize-b.scala +++ b/tests/warn/type-test-syntesize-b.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + import scala.reflect.TypeTest @@ -19,13 +19,13 @@ object Test { test[Any, Array[Int]] test[Seq[Int], List[Int]] - test[Any, Some[Int]] // error - test[Any, a.X] // error - test[a.X, a.Y] // error + test[Any, Some[Int]] // warn + test[Any, a.X] // warn + test[a.X, a.Y] // warn } class A { type X type Y <: X -} +} \ No newline at end of file diff --git a/tests/neg/uninitialized-3.4.check b/tests/warn/uninitialized-3.4.check similarity index 75% rename from tests/neg/uninitialized-3.4.check rename to tests/warn/uninitialized-3.4.check index 1c7b985072d0..ddf4bfed85ed 100644 --- a/tests/neg/uninitialized-3.4.check +++ b/tests/warn/uninitialized-3.4.check @@ -1,5 +1,5 @@ --- Error: tests/neg/uninitialized-3.4.scala:7:15 ----------------------------------------------------------------------- -7 | var a: Int = _ // error: migration warning +-- Warning: tests/warn/uninitialized-3.4.scala:5:15 -------------------------------------------------------------------- +5 | var a: Int = _ // warn | ^ | `= _` has been deprecated; use `= uninitialized` instead. | `uninitialized` can be imported with `scala.compiletime.uninitialized`. diff --git a/tests/neg/uninitialized-3.4.scala b/tests/warn/uninitialized-3.4.scala similarity index 60% rename from tests/neg/uninitialized-3.4.scala rename to tests/warn/uninitialized-3.4.scala index 174a95ae6c54..966f2e51af1c 100644 --- a/tests/neg/uninitialized-3.4.scala +++ b/tests/warn/uninitialized-3.4.scala @@ -1,8 +1,6 @@ -//> using options -Werror - import scala.language.`3.4` import scala.compiletime.uninitialized class Foo: - var a: Int = _ // error: migration warning + var a: Int = _ // warn var b: Int = uninitialized diff --git a/tests/neg/uninitialized-future-migration.scala b/tests/warn/uninitialized-future-migration.scala similarity index 62% rename from tests/neg/uninitialized-future-migration.scala rename to tests/warn/uninitialized-future-migration.scala index 05f7c6b67f38..7c24f2466221 100644 --- a/tests/neg/uninitialized-future-migration.scala +++ b/tests/warn/uninitialized-future-migration.scala @@ -1,8 +1,6 @@ -//> using options -Werror - import scala.language.`future-migration` import scala.compiletime.uninitialized class Foo: - var a: Int = _ // error: migration warning + var a: Int = _ // warn: migration warning var b: Int = uninitialized diff --git a/tests/warn/warn-value-discard.check b/tests/warn/warn-value-discard.check new file mode 100644 index 000000000000..ca6fedb29053 --- /dev/null +++ b/tests/warn/warn-value-discard.check @@ -0,0 +1,20 @@ +-- [E175] Potential Issue Warning: tests/warn/warn-value-discard.scala:27:36 ------------------------------------------- +27 | mutable.Set.empty[String].remove("") // warn + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | discarded non-Unit value of type Boolean +-- [E175] Potential Issue Warning: tests/warn/warn-value-discard.scala:39:41 ------------------------------------------- +39 | mutable.Set.empty[String].subtractOne("") // warn + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | discarded non-Unit value of type scala.collection.mutable.Set[String] +-- [E175] Potential Issue Warning: tests/warn/warn-value-discard.scala:59:4 -------------------------------------------- +59 | mutable.Set.empty[String] += "" // warn + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | discarded non-Unit value of type scala.collection.mutable.Set[String] +-- [E175] Potential Issue Warning: tests/warn/warn-value-discard.scala:15:35 ------------------------------------------- +15 | firstThing().map(_ => secondThing()) // warn + | ^^^^^^^^^^^^^ + | discarded non-Unit value of type Either[Failed, Unit] +-- [E175] Potential Issue Warning: tests/warn/warn-value-discard.scala:18:35 ------------------------------------------- +18 | firstThing().map(_ => secondThing()) // warn + | ^^^^^^^^^^^^^ + | discarded non-Unit value of type Either[Failed, Unit] diff --git a/tests/neg/warn-value-discard.scala b/tests/warn/warn-value-discard.scala similarity index 84% rename from tests/neg/warn-value-discard.scala rename to tests/warn/warn-value-discard.scala index fb01fdeda384..8bb9aebf515b 100644 --- a/tests/neg/warn-value-discard.scala +++ b/tests/warn/warn-value-discard.scala @@ -1,4 +1,4 @@ -//> using options -Wvalue-discard -Werror +//> using options -Wvalue-discard import scala.util.{Either, Right, Left} import scala.collection.mutable @@ -12,10 +12,10 @@ def secondThing(): Either[Failed, Unit] = Left(Failed("whoops you should have flatMapped me")) def singleExpr(): Either[Failed, Unit] = - firstThing().map(_ => secondThing()) // error + firstThing().map(_ => secondThing()) // warn def block(): Either[Failed, Unit] = { - firstThing().map(_ => secondThing()) // error + firstThing().map(_ => secondThing()) // warn } class ValueDiscardTest: @@ -24,7 +24,7 @@ class ValueDiscardTest: def remove(): Unit = // Set#remove returns a Boolean, not this.type // --> Warning - mutable.Set.empty[String].remove("") // error + mutable.Set.empty[String].remove("") // warn // TODO IMHO we don't need to support this, // as it's just as easy to add a @nowarn annotation as a Unit ascription @@ -36,7 +36,7 @@ class ValueDiscardTest: // - Set#subtractOne returns this.type // - receiver is not a field or a local variable (not quite sure what you'd call it) // --> Warning - mutable.Set.empty[String].subtractOne("") // error + mutable.Set.empty[String].subtractOne("") // warn def mutateLocalVariable(): Unit = { // - Set#subtractOne returns this.type @@ -56,11 +56,11 @@ class ValueDiscardTest: // - += returns this.type // - receiver is not a field or a local variable // --> Warning - mutable.Set.empty[String] += "" // error + mutable.Set.empty[String] += "" // warn def assignmentOperatorLocalVariable(): Unit = // - += returns this.type // - receiver is a local variable // --> No warning val s: mutable.Set[String] = mutable.Set.empty[String] - s += "" + s += "" \ No newline at end of file diff --git a/tests/neg/with-type-operator-future-migration.check b/tests/warn/with-type-operator-future-migration.check similarity index 61% rename from tests/neg/with-type-operator-future-migration.check rename to tests/warn/with-type-operator-future-migration.check index e56049880431..2842592bee64 100644 --- a/tests/neg/with-type-operator-future-migration.check +++ b/tests/warn/with-type-operator-future-migration.check @@ -1,5 +1,5 @@ --- [E003] Syntax Error: tests/neg/with-type-operator-future-migration.scala:5:13 --------------------------------------- -5 |def foo: Int with String = ??? // error +-- [E003] Syntax Migration Warning: tests/warn/with-type-operator-future-migration.scala:5:13 -------------------------- +5 |def foo: Int with String = ??? // warn | ^^^^ | with as a type operator has been deprecated; use & instead | This construct can be rewritten automatically under -rewrite -source 3.4-migration. diff --git a/tests/warn/with-type-operator-future-migration.scala b/tests/warn/with-type-operator-future-migration.scala new file mode 100644 index 000000000000..42b029665565 --- /dev/null +++ b/tests/warn/with-type-operator-future-migration.scala @@ -0,0 +1,6 @@ + + +import scala.language.`future-migration` + +def foo: Int with String = ??? // warn + diff --git a/tests/neg/xfatalWarnings.scala b/tests/warn/xfatalWarnings.scala similarity index 69% rename from tests/neg/xfatalWarnings.scala rename to tests/warn/xfatalWarnings.scala index 3f49e159cbc4..7e77ac468370 100644 --- a/tests/neg/xfatalWarnings.scala +++ b/tests/warn/xfatalWarnings.scala @@ -1,9 +1,9 @@ -//> using options -Xfatal-warnings + object xfatalWarnings { val opt:Option[String] = Some("test") - opt match { // error when running with -Xfatal-warnings + opt match { // warn case None => } @@ -11,3 +11,5 @@ object xfatalWarnings { while (true) {} // should be ok. no "pure expression does nothing in statement position" issued. } } + +// When running with fatal warnings: From 69d1de3640286b2cf131327f0ba64380e3288015 Mon Sep 17 00:00:00 2001 From: Szymon Rodziewicz Date: Fri, 12 Jan 2024 14:34:12 +0100 Subject: [PATCH 2/2] Review fixes --- tests/neg-deep-subtype/1828.scala | 11 ---- tests/neg-deep-subtype/3324b.scala | 11 ---- tests/neg-deep-subtype/3324f.scala | 11 ---- tests/neg-deep-subtype/3324g.scala | 21 ------- tests/neg-deep-subtype/JavaSeqLiteral.scala | 31 ---------- .../conditionalWarnings.scala | 15 ----- tests/neg-deep-subtype/gadt.scala | 15 ----- tests/neg-deep-subtype/html.scala | 20 ------- tests/neg-deep-subtype/or-type-trees.scala | 40 ------------- tests/neg-deep-subtype/refined-types.scala | 24 -------- tests/neg-deep-subtype/t2755.scala | 60 ------------------- tests/neg-deep-subtype/type-lambda.scala | 16 ----- tests/warn/opaque-match.scala | 2 +- 13 files changed, 1 insertion(+), 276 deletions(-) delete mode 100644 tests/neg-deep-subtype/1828.scala delete mode 100644 tests/neg-deep-subtype/3324b.scala delete mode 100644 tests/neg-deep-subtype/3324f.scala delete mode 100644 tests/neg-deep-subtype/3324g.scala delete mode 100644 tests/neg-deep-subtype/JavaSeqLiteral.scala delete mode 100644 tests/neg-deep-subtype/conditionalWarnings.scala delete mode 100644 tests/neg-deep-subtype/gadt.scala delete mode 100644 tests/neg-deep-subtype/html.scala delete mode 100644 tests/neg-deep-subtype/or-type-trees.scala delete mode 100644 tests/neg-deep-subtype/refined-types.scala delete mode 100644 tests/neg-deep-subtype/t2755.scala delete mode 100644 tests/neg-deep-subtype/type-lambda.scala diff --git a/tests/neg-deep-subtype/1828.scala b/tests/neg-deep-subtype/1828.scala deleted file mode 100644 index ae228a83e898..000000000000 --- a/tests/neg-deep-subtype/1828.scala +++ /dev/null @@ -1,11 +0,0 @@ -//> using options -Xfatal-warnings - -class Test { - def remove[S](a: S | Int, f: Int => S):S = a match { - case a: S => a // error - case a: Int => f(a) - } - - val t: Int | String = 5 - val t1 = remove[String](t, _.toString) -} diff --git a/tests/neg-deep-subtype/3324b.scala b/tests/neg-deep-subtype/3324b.scala deleted file mode 100644 index df0cc5432eff..000000000000 --- a/tests/neg-deep-subtype/3324b.scala +++ /dev/null @@ -1,11 +0,0 @@ -//> using options -Xfatal-warnings - -class C[T] { - val x: Any = ??? - if (x.isInstanceOf[List[String]]) // error: unchecked - if (x.isInstanceOf[T]) // error: unchecked - x match { - case x: List[String] => // error: unchecked - case x: T => // error: unchecked - } -} diff --git a/tests/neg-deep-subtype/3324f.scala b/tests/neg-deep-subtype/3324f.scala deleted file mode 100644 index 445da5cb25a0..000000000000 --- a/tests/neg-deep-subtype/3324f.scala +++ /dev/null @@ -1,11 +0,0 @@ -//> using options -Xfatal-warnings - -trait C[T] -class D[T] - -class Test { - def foo[T](x: C[T]) = x match { - case _: D[T] => // error - case _: C[Int] => // error - } -} \ No newline at end of file diff --git a/tests/neg-deep-subtype/3324g.scala b/tests/neg-deep-subtype/3324g.scala deleted file mode 100644 index a5b842e4e450..000000000000 --- a/tests/neg-deep-subtype/3324g.scala +++ /dev/null @@ -1,21 +0,0 @@ -//> using options -Xfatal-warnings - -class Test { - trait A[+T] - class B[T] extends A[T] - class C[T] extends B[Any] with A[T] - - def foo[T](c: C[T]): Unit = c match { - case _: B[T] => // error - } - - def bar[T](b: B[T]): Unit = b match { - case _: A[T] => - } - - def quux[T](a: A[T]): Unit = a match { - case _: B[T] => // error!! - } - - quux(new C[Int]) -} diff --git a/tests/neg-deep-subtype/JavaSeqLiteral.scala b/tests/neg-deep-subtype/JavaSeqLiteral.scala deleted file mode 100644 index 6003731ae657..000000000000 --- a/tests/neg-deep-subtype/JavaSeqLiteral.scala +++ /dev/null @@ -1,31 +0,0 @@ -//> using options -Xfatal-warnings - -object Test1 { - trait Tree[-T] - - class JavaSeqLiteral[T] extends Tree[T] - - trait Type - - class DummyTree extends JavaSeqLiteral[Any] - - def foo1(tree: Tree[Type]) = - tree.isInstanceOf[JavaSeqLiteral[Type]] // error - - foo1(new DummyTree) -} - -object Test2 { - trait Tree[-T] - - class JavaSeqLiteral[-T] extends Tree[T] - - trait Type - - class DummyTree extends JavaSeqLiteral[Any] - - def foo1(tree: Tree[Type]) = - tree.isInstanceOf[JavaSeqLiteral[Type]] - - foo1(new DummyTree) -} \ No newline at end of file diff --git a/tests/neg-deep-subtype/conditionalWarnings.scala b/tests/neg-deep-subtype/conditionalWarnings.scala deleted file mode 100644 index c4757cbb7546..000000000000 --- a/tests/neg-deep-subtype/conditionalWarnings.scala +++ /dev/null @@ -1,15 +0,0 @@ -//> using options -deprecation -Xfatal-warnings - -object Test { - @deprecated def foo = ??? - - given Conversion[String, Int] = _.length - - foo // error - - val x: Int = "abc" - // OK, since -feature warnings are not enabled. - // The program compiles with final line - // there was 1 feature warning; re-run with -feature for details - // nopos-error -} diff --git a/tests/neg-deep-subtype/gadt.scala b/tests/neg-deep-subtype/gadt.scala deleted file mode 100644 index 661c04fef373..000000000000 --- a/tests/neg-deep-subtype/gadt.scala +++ /dev/null @@ -1,15 +0,0 @@ -//> using options -Xfatal-warnings - -class Test { - trait A[+T] - class B[T] extends A[T] - - class C - class D extends C - - def quux(a: A[C]): Unit = a match { - case _: B[C] => // error!! - } - - quux(new B[D]) -} \ No newline at end of file diff --git a/tests/neg-deep-subtype/html.scala b/tests/neg-deep-subtype/html.scala deleted file mode 100644 index f17cfb661505..000000000000 --- a/tests/neg-deep-subtype/html.scala +++ /dev/null @@ -1,20 +0,0 @@ -//> using options -Xfatal-warnings - -object HTML: - type AttrArg = AppliedAttr | Seq[AppliedAttr] - opaque type AppliedAttr = String - opaque type AppliedTag = StringBuilder - - case class Tag(name: String): - def apply(attrs: AttrArg*): AppliedTag = { - val sb = StringBuilder() - sb.append(s"<$name") - attrs.filter(_ != Nil).foreach{ - case s: Seq[AppliedAttr] => - s.foreach(sb.append(" ").append) - case s: Seq[Int] => // error - case e: AppliedAttr => - sb.append(" ").append(e) - } - sb - } diff --git a/tests/neg-deep-subtype/or-type-trees.scala b/tests/neg-deep-subtype/or-type-trees.scala deleted file mode 100644 index d0338ffe6066..000000000000 --- a/tests/neg-deep-subtype/or-type-trees.scala +++ /dev/null @@ -1,40 +0,0 @@ -//> using options -Xfatal-warnings - -object Test1 { - trait Tree - trait Context - - def foo1(myTree: Tree | (Context => Tree)) = - println(myTree.isInstanceOf[Tree]) - - def foo2(myTree: Tree | (Context => Tree)) = - myTree match - case treeFn: (Context => Tree) => // error - case _ => - - def foo3(myTree: Tree | (Context => Tree)) = - myTree match - case treeFn: (? => ?) => // ok - case _ => -} - -object Test2 { - trait Tree[-T] - trait Context - - trait Type - - def foo1(myTree: Tree[Type] | (Context => Tree[Type])) = - println(myTree.isInstanceOf[Tree[Type]]) // error - /* class DummyTree extends Tree[Nothing] with (Context => Tree[Type]) */ - - def foo2(myTree: Tree[Type] | (Context => Tree[Type])) = - myTree match - case treeFn: (Context => Tree[Type]) => // error - case _ => - - def foo3(myTree: Tree[Type] | (Context => Tree[Type])) = - myTree match - case treeFn: (? => ?) => // ok - case _ => -} \ No newline at end of file diff --git a/tests/neg-deep-subtype/refined-types.scala b/tests/neg-deep-subtype/refined-types.scala deleted file mode 100644 index 5f5cc5a45f04..000000000000 --- a/tests/neg-deep-subtype/refined-types.scala +++ /dev/null @@ -1,24 +0,0 @@ -//> using options -Xfatal-warnings - -class A -class B extends A -type AA = A { type T = Int } -type BA = B { type T = Int } -type AL = A { type T >: Int } -type BL = B { type T >: Int } -type AU = A { type T <: Int } -type BU = B { type T <: Int } - -def aa(x: AA) = x.isInstanceOf[BA] // was: the type test for BA cannot be checked at runtime -def al(x: AL) = x.isInstanceOf[BL] // was: the type test for BL cannot be checked at runtime -def au(x: AU) = x.isInstanceOf[BU] // was: the type test for BU cannot be checked at runtime - -// an alias leaves nothing unchecked when type testing against one bound: -def bl(x: AA) = x.isInstanceOf[BL] // was: the type test for BL cannot be checked at runtime -def bu(x: AA) = x.isInstanceOf[BU] // was: the type test for BU cannot be checked at runtime - -// but static knowledge of only one bound makes checking against an alias unchecked: -def al_ba(x: AL) = x.isInstanceOf[BA] // error: the type test for BA cannot be checked at runtime -def au_ba(x: AU) = x.isInstanceOf[BA] // error: the type test for BA cannot be checked at runtime -def al_bu(x: AL) = x.isInstanceOf[BU] // error: the type test for BU cannot be checked at runtime -def au_bl(x: AU) = x.isInstanceOf[BL] // error: the type test for BL cannot be checked at runtime diff --git a/tests/neg-deep-subtype/t2755.scala b/tests/neg-deep-subtype/t2755.scala deleted file mode 100644 index ec3cb6aadefc..000000000000 --- a/tests/neg-deep-subtype/t2755.scala +++ /dev/null @@ -1,60 +0,0 @@ -//> using options -Xfatal-warnings - -// Test cases: the only place we can cut and paste without crying -// ourself to sleep. -object Test { - def f1(a: Any) = a match { - case x: Array[Int] => x(0) - case x: Array[Double] => 2 - case x: Array[Float] => x.sum.toInt - case x: Array[String] => x.size - case x: Array[AnyRef] => 5 - case x: Array[?] => 6 - case _ => 7 - } - def f2(a: Array[?]) = a match { - case x: Array[Int] => x(0) - case x: Array[Double] => 2 - case x: Array[Float] => x.sum.toInt - case x: Array[String] => x.size - case x: Array[AnyRef] => 5 - case x: Array[?] => 6 - case _ => 7 // error: only null is matched - } - def f3[T](a: Array[T]) = a match { - case x: Array[Int] => x(0) - case x: Array[Double] => 2 - case x: Array[Float] => x.sum.toInt - case x: Array[String] => x.size - case x: Array[AnyRef] => 5 - case x: Array[?] => 6 - case _ => 7 // error: only null is matched - } - - - def main(args: Array[String]): Unit = { - println(f1(Array(1, 2, 3))) - println(f1(Array(1.0, -2.0, 3.0, 1.0))) - println(f1(Array(1.0f, 2.0f, 3.0f, -3.0f))) - println(f1((1 to 4).toArray map (_.toString))) - println(f1(new Array[Any](10))) // should match as Array[AnyRef] - println(f1(Array(1L))) - println(f1(null)) - - println(f2(Array(1, 2, 3))) - println(f2(Array(1.0, -2.0, 3.0, 1.0))) - println(f2(Array(1.0f, 2.0f, 3.0f, -3.0f))) - println(f2((1 to 4).toArray map (_.toString))) - println(f2(new Array[Any](10))) // should match as Array[AnyRef] - println(f2(Array(1L))) - println(f2(null)) - - println(f3(Array(1, 2, 3))) - println(f3(Array(1.0, -2.0, 3.0, 1.0))) - println(f3(Array(1.0f, 2.0f, 3.0f, -3.0f))) - println(f3((1 to 4).toArray map (_.toString))) - println(f3(new Array[Any](10))) // should match as Array[AnyRef] - println(f3(Array(1L))) - println(f3(null)) - } -} diff --git a/tests/neg-deep-subtype/type-lambda.scala b/tests/neg-deep-subtype/type-lambda.scala deleted file mode 100644 index 4c4627fe1cf3..000000000000 --- a/tests/neg-deep-subtype/type-lambda.scala +++ /dev/null @@ -1,16 +0,0 @@ -//> using options -Xfatal-warnings - -trait A[T] -trait B[T] extends A[T] - -object Test { - def foo(x: ([X] =>> A[X])[Any]) = x match { - case x: ([X] =>> B[X])[Any] => - case _ => - } - - def bar(x: ([X] =>> A[X])[Any]) = x match { - case x: ([X] =>> B[Nothing])[Any] => // error - case _ => - } -} diff --git a/tests/warn/opaque-match.scala b/tests/warn/opaque-match.scala index 453d525bac2c..06cca835ab91 100644 --- a/tests/warn/opaque-match.scala +++ b/tests/warn/opaque-match.scala @@ -21,4 +21,4 @@ def Test[T] = (??? : Any) match case _: List[O.T @unchecked] => ??? // OK (??? : Any) match - case _: List[T] => ??? // warn \ No newline at end of file + case _: List[T] => ??? // warn