diff --git a/compiler/test/dotty/tools/dotc/transform/PatmatExhaustivityTest.scala b/compiler/test/dotty/tools/dotc/transform/PatmatExhaustivityTest.scala index a0c46c829d0d..7938a4e5af47 100644 --- a/compiler/test/dotty/tools/dotc/transform/PatmatExhaustivityTest.scala +++ b/compiler/test/dotty/tools/dotc/transform/PatmatExhaustivityTest.scala @@ -10,28 +10,25 @@ import reporting.TestReporter import dotty.tools.io.Directory import java.io._ -import java.nio.file.{Path => JPath} +import java.nio.file.{Files, Path => JPath} import scala.io.Source._ import org.junit.Test -class PatmatDefaultExhaustivityTest extends PatmatExhaustivityTest { - override val testsDir = "tests/patmat-default" - override val options = super.options.filter(_ != "-Ycheck-all-patmat") -} - class PatmatExhaustivityTest { val testsDir = "tests/patmat" - // stop-after: patmatexhaust-huge.scala crash compiler - def options = List("-pagewidth", "80", "-color:never", "-Ystop-after:explicitSelf", "-Ycheck-all-patmat", "-classpath", TestConfiguration.basicClasspath) + // pagewidth/color: for a stable diff as the defaults are based on the terminal (e.g size) + // stop-after: patmatexhaust-huge.scala crash compiler (but also hides other warnings..) + val options = List("-pagewidth", "80", "-color:never", "-Ystop-after:explicitSelf", "-classpath", TestConfiguration.basicClasspath) - private def compile(files: Seq[String]): Seq[String] = { + private def compile(files: List[JPath]): Seq[String] = { + val opts = toolArgsFor(files) val stringBuffer = new StringWriter() val printWriter = new PrintWriter(stringBuffer) val reporter = TestReporter.simplifiedReporter(printWriter) try { - Main.process((options ++ files).toArray, reporter, null) + Main.process((options ::: opts ::: files.map(_.toString)).toArray, reporter, null) } catch { case e: Throwable => e.printStackTrace(printWriter) @@ -44,7 +41,7 @@ class PatmatExhaustivityTest { } private def compileFile(path: JPath): Boolean = { - val actualLines = compile(path.toString :: Nil) + val actualLines = compile(List(path)) val baseFilePath = path.toString.stripSuffix(".scala") val checkFilePath = baseFilePath + ".check" @@ -55,7 +52,7 @@ class PatmatExhaustivityTest { private def compileDir(path: JPath): Boolean = { val files = Directory(path).list.toList .filter(f => f.extension == "scala" || f.extension == "java" ) - .map(_.jpath.toString) + .map(_.jpath) val actualLines = compile(files) val checkFilePath = s"${path}${File.separator}expected.check" @@ -67,12 +64,7 @@ class PatmatExhaustivityTest { def patmatExhaustivity: Unit = { val res = Directory(testsDir).list.toList .filter(f => f.extension == "scala" || f.isDirectory) - .map { f => - if (f.isDirectory) - compileDir(f.jpath) - else - compileFile(f.jpath) - } + .map(f => if f.isDirectory then compileDir(f.jpath) else compileFile(f.jpath)) val failed = res.filter(!_) val ignored = Directory(testsDir).list.toList.filter(_.extension == "ignore") @@ -83,4 +75,22 @@ class PatmatExhaustivityTest { println(msg) } + + // inspect given files for tool args of the form `tool: args` + // if args string ends in close comment, drop the `*` `/` + // if split, parse the args string as command line. + // (from scala.tools.partest.nest.Runner#toolArgsFor) + private def toolArgsFor(files: List[JPath]): List[String] = { + import scala.jdk.OptionConverters._ + import config.CommandLineParser.tokenize + files.flatMap { path => + val tag = "scalac:" + val endc = "*" + "/" // be forgiving of /* scalac: ... */ + def stripped(s: String) = s.substring(s.indexOf(tag) + tag.length).stripSuffix(endc) + val args = scala.util.Using.resource(Files.lines(path, scala.io.Codec.UTF8.charSet))( + _.limit(10).filter(_.contains(tag)).map(stripped).findAny.toScala + ) + args.map(tokenize).getOrElse(Nil) + } + } } diff --git a/tests/patmat/i10174b.check b/tests/patmat/i10174b.check index a8e6f96b4bac..582ce090b23d 100644 --- a/tests/patmat/i10174b.check +++ b/tests/patmat/i10174b.check @@ -1,2 +1,2 @@ -2: Pattern Match Exhaustivity: _: Int -58: Match case Unreachable +3: Pattern Match Exhaustivity: _: Int +59: Match case Unreachable diff --git a/tests/patmat/i10174b.scala b/tests/patmat/i10174b.scala index f227f68c909b..875e19e8f037 100644 --- a/tests/patmat/i10174b.scala +++ b/tests/patmat/i10174b.scala @@ -1,3 +1,4 @@ +// scalac: -Ycheck-all-patmat def foo(x: Int): Unit = x match { case 1 => @@ -1001,4 +1002,4 @@ def foo(x: Int): Unit = case 998 => case 999 => case 1000 => - } \ No newline at end of file + } diff --git a/tests/patmat-default/i12485.scala b/tests/patmat/i12485.scala similarity index 100% rename from tests/patmat-default/i12485.scala rename to tests/patmat/i12485.scala diff --git a/tests/patmat-default/i13003.check b/tests/patmat/i13003.check similarity index 100% rename from tests/patmat-default/i13003.check rename to tests/patmat/i13003.check diff --git a/tests/patmat-default/i13003.scala b/tests/patmat/i13003.scala similarity index 100% rename from tests/patmat-default/i13003.scala rename to tests/patmat/i13003.scala diff --git a/tests/patmat/i6197d.check b/tests/patmat/i6197d.check index 1f4a130c3f86..cb1b11d4b326 100644 --- a/tests/patmat/i6197d.check +++ b/tests/patmat/i6197d.check @@ -1 +1 @@ -5: Pattern Match Exhaustivity: _: Array[String] +6: Pattern Match Exhaustivity: _: Array[String] diff --git a/tests/patmat/i6197d.scala b/tests/patmat/i6197d.scala index 247a5f12020d..419c6e7ec2fa 100644 --- a/tests/patmat/i6197d.scala +++ b/tests/patmat/i6197d.scala @@ -1,7 +1,8 @@ +// scalac: -Ycheck-all-patmat def foo(x: Array[String]) = x match { case _: Array[_] => } def bar(x: Array[String]) = x match { case _: Array[_ <: Int] => -} \ No newline at end of file +} diff --git a/tests/patmat/i6255b.check b/tests/patmat/i6255b.check index 582d2e65bc51..265ec9fa9c4b 100644 --- a/tests/patmat/i6255b.check +++ b/tests/patmat/i6255b.check @@ -1 +1 @@ -2: Pattern Match Exhaustivity: _: Expr[Int] +3: Pattern Match Exhaustivity: _: Expr[Int] diff --git a/tests/patmat/i6255b.scala b/tests/patmat/i6255b.scala index a5c52c8f28dc..02fba4ad9100 100644 --- a/tests/patmat/i6255b.scala +++ b/tests/patmat/i6255b.scala @@ -1,3 +1,4 @@ +// scalac: -Ycheck-all-patmat class Foo { def foo(x: quoted.Expr[Int])(using scala.quoted.Quotes): Unit = x match { case '{ 1 } => diff --git a/tests/patmat/patmat-indent.check b/tests/patmat/patmat-indent.check index 4f0ec4dd99df..7689dd60d8bf 100644 --- a/tests/patmat/patmat-indent.check +++ b/tests/patmat/patmat-indent.check @@ -1,3 +1,3 @@ -9: Pattern Match Exhaustivity: Nil -23: Pattern Match Exhaustivity: true, false -27: Pattern Match Exhaustivity: _: Int +10: Pattern Match Exhaustivity: Nil +24: Pattern Match Exhaustivity: true, false +28: Pattern Match Exhaustivity: _: Int diff --git a/tests/patmat/patmat-indent.scala b/tests/patmat/patmat-indent.scala index a2b18e7fb1f8..f62d704f8ca0 100644 --- a/tests/patmat/patmat-indent.scala +++ b/tests/patmat/patmat-indent.scala @@ -1,3 +1,4 @@ +// scalac: -Ycheck-all-patmat object Test { val Nil: scala.collection.immutable.Nil.type = scala.collection.immutable.Nil val X = 5 @@ -27,4 +28,4 @@ object Test { def foo3(x: Int) = x match { case X => 0 } -} \ No newline at end of file +} diff --git a/tests/patmat/t10502.check b/tests/patmat/t10502.check index b92e0d7cae8a..11be4c628b63 100644 --- a/tests/patmat/t10502.check +++ b/tests/patmat/t10502.check @@ -1,4 +1,4 @@ -5: Pattern Match Exhaustivity: Perhaps(None) -15: Pattern Match Exhaustivity: Nil -31: Pattern Match Exhaustivity: Multi(None, _) -44: Pattern Match Exhaustivity: Prod(None, _) +6: Pattern Match Exhaustivity: Perhaps(None) +16: Pattern Match Exhaustivity: Nil +32: Pattern Match Exhaustivity: Multi(None, _) +45: Pattern Match Exhaustivity: Prod(None, _) diff --git a/tests/patmat/t10502.scala b/tests/patmat/t10502.scala index adf6b4df49fa..71066fdb7ae8 100644 --- a/tests/patmat/t10502.scala +++ b/tests/patmat/t10502.scala @@ -1,3 +1,4 @@ +// scalac: -Ycheck-all-patmat object Perhaps { def unapply[A](oa: Option[A]): Some[Option[A]] = Some(oa) diff --git a/tests/patmat/t3163.check b/tests/patmat/t3163.check index 51c58f9e3fe8..15f00dbfcebe 100644 --- a/tests/patmat/t3163.check +++ b/tests/patmat/t3163.check @@ -1 +1 @@ -2: Pattern Match Exhaustivity: _: AnyVal +3: Pattern Match Exhaustivity: _: AnyVal diff --git a/tests/patmat/t3163.scala b/tests/patmat/t3163.scala index 2e0f2c1d9482..19aa6fe93ca8 100644 --- a/tests/patmat/t3163.scala +++ b/tests/patmat/t3163.scala @@ -1,3 +1,4 @@ +// scalac: -Ycheck-all-patmat object Test { def foo(x : AnyVal) = x match {case b : Boolean => "It's a bool"} -} \ No newline at end of file +} diff --git a/tests/patmat/t4526.check b/tests/patmat/t4526.check index ac3ef01bcc23..17e8200e9b1d 100644 --- a/tests/patmat/t4526.check +++ b/tests/patmat/t4526.check @@ -1,3 +1,3 @@ -2: Pattern Match Exhaustivity: _: Int -7: Pattern Match Exhaustivity: (_, _) -12: Pattern Match Exhaustivity: (true, true), (false, false) +3: Pattern Match Exhaustivity: _: Int +8: Pattern Match Exhaustivity: (_, _) +13: Pattern Match Exhaustivity: (true, true), (false, false) diff --git a/tests/patmat/t4526.scala b/tests/patmat/t4526.scala index d531c6b34304..016f3782b65b 100644 --- a/tests/patmat/t4526.scala +++ b/tests/patmat/t4526.scala @@ -1,3 +1,4 @@ +// scalac: -Ycheck-all-patmat object Test{ def foo(a: Int) = a match { case 5 => "Five!" @@ -13,4 +14,4 @@ object Test{ case (true, false) => "tf" case (false, true) => "ft" } -} \ No newline at end of file +} diff --git a/tests/patmat/t4661b.check b/tests/patmat/t4661b.check index 50b0c4da452e..d19d4c6db744 100644 --- a/tests/patmat/t4661b.check +++ b/tests/patmat/t4661b.check @@ -1,2 +1,2 @@ -10: Pattern Match Exhaustivity: _: c.Foo -13: Match case Unreachable +11: Pattern Match Exhaustivity: _: c.Foo +14: Match case Unreachable diff --git a/tests/patmat/t4661b.scala b/tests/patmat/t4661b.scala index ee95ff08ca07..f2329020cb66 100644 --- a/tests/patmat/t4661b.scala +++ b/tests/patmat/t4661b.scala @@ -1,3 +1,4 @@ +// scalac: -Ycheck-all-patmat class C { trait Foo class One extends Foo diff --git a/tests/patmat/t9351.check b/tests/patmat/t9351.check index 379adffd5a61..b5baf54469fc 100644 --- a/tests/patmat/t9351.check +++ b/tests/patmat/t9351.check @@ -1,3 +1,3 @@ -8: Pattern Match Exhaustivity: _: A -17: Pattern Match Exhaustivity: (_, _) -28: Pattern Match Exhaustivity: (_, _) +9: Pattern Match Exhaustivity: _: A +18: Pattern Match Exhaustivity: (_, _) +29: Pattern Match Exhaustivity: (_, _) diff --git a/tests/patmat/t9351.scala b/tests/patmat/t9351.scala index 9b9bd4312ae7..b43fa948ce87 100644 --- a/tests/patmat/t9351.scala +++ b/tests/patmat/t9351.scala @@ -1,3 +1,4 @@ +// scalac: -Ycheck-all-patmat trait A {} case object B extends A {} case object C extends A {} diff --git a/tests/patmat/t9809.check b/tests/patmat/t9809.check index ff3fb4c63f64..6baed9fb58f0 100644 --- a/tests/patmat/t9809.check +++ b/tests/patmat/t9809.check @@ -1,2 +1,2 @@ -3: Pattern Match Exhaustivity: (_, _) -7: Pattern Match Exhaustivity: (_, _) +4: Pattern Match Exhaustivity: (_, _) +8: Pattern Match Exhaustivity: (_, _) diff --git a/tests/patmat/t9809.scala b/tests/patmat/t9809.scala index 45d4946cdbe4..72ff23b11e51 100644 --- a/tests/patmat/t9809.scala +++ b/tests/patmat/t9809.scala @@ -1,3 +1,4 @@ +// scalac: -Ycheck-all-patmat object Example { val op1: (Any, Any) => Unit = { case (_, b: Int) =>