From 1af99652dfb529f92b4af67ed993fd29e79411fd Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 17 Oct 2023 10:26:47 +0100 Subject: [PATCH 1/4] Vulpix: Remove unused logStackTrace & downstream usages [Cherry-picked 9c92162fdc5dfe3edb9cfa744158e1f6e6050b8a] --- .../dotty/tools/dotc/reporting/TestReporter.scala | 11 ----------- .../test/dotty/tools/vulpix/ParallelTesting.scala | 9 +++------ 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/compiler/test/dotty/tools/dotc/reporting/TestReporter.scala b/compiler/test/dotty/tools/dotc/reporting/TestReporter.scala index c0ece68e3b46..03b61c393d35 100644 --- a/compiler/test/dotty/tools/dotc/reporting/TestReporter.scala +++ b/compiler/test/dotty/tools/dotc/reporting/TestReporter.scala @@ -32,9 +32,6 @@ extends Reporter with UniqueMessagePositions with HideNonSensicalMessages with M protected final val _consoleReporter = new ConsoleReporter(null, new PrintWriter(_consoleBuf)) final def consoleOutput: String = _consoleBuf.toString - private var _didCrash = false - final def compilerCrashed: Boolean = _didCrash - private var _skip: Boolean = false final def setSkip(): Unit = _skip = true final def skipped: Boolean = _skip @@ -50,14 +47,6 @@ extends Reporter with UniqueMessagePositions with HideNonSensicalMessages with M def log(msg: String) = _messageBuf.append(msg) - def logStackTrace(thrown: Throwable): Unit = { - _didCrash = true - val sw = new java.io.StringWriter - val pw = new java.io.PrintWriter(sw) - thrown.printStackTrace(pw) - log(sw.toString) - } - /** Prints the message with the given position indication. */ def printMessageAndPos(dia: Diagnostic, extra: String)(using Context): Unit = { val msg = messageAndPos(dia) diff --git a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala index 4e6fe67aec37..b9586faf01ce 100644 --- a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala +++ b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala @@ -244,7 +244,7 @@ trait ParallelTesting extends RunnerOrchestration { self => final def countErrors (reporters: Seq[TestReporter]) = countErrorsAndWarnings(reporters)._1 final def countWarnings(reporters: Seq[TestReporter]) = countErrorsAndWarnings(reporters)._2 - final def reporterFailed(r: TestReporter) = r.compilerCrashed || r.errorCount > 0 + final def reporterFailed(r: TestReporter) = r.errorCount > 0 /** * For a given test source, returns a check file against which the result of the test run @@ -737,8 +737,7 @@ trait ParallelTesting extends RunnerOrchestration { self => def showDiagnostics = "-> following the diagnostics:\n" + reporters.flatMap(_.diagnostics.toSeq.sortBy(_.pos.line).map(e => s"${e.pos.line + 1}: ${e.message}")).mkString(" at ", "\n at ", "") Option: - if reporters.exists(_.compilerCrashed) then s"Compiler crashed when compiling: ${testSource.title}" - else if reporters.exists(_.errorCount > 0) then + if reporters.exists(_.errorCount > 0) then s"""Compilation failed for: ${testSource.title} |$showDiagnostics |""".stripMargin.trim.linesIterator.mkString("\n", "\n", "") @@ -862,7 +861,6 @@ trait ParallelTesting extends RunnerOrchestration { self => override def suppressErrors = true override def maybeFailureMessage(testSource: TestSource, reporters: Seq[TestReporter]): Option[String] = - def compilerCrashed = reporters.exists(_.compilerCrashed) lazy val (errorMap, expectedErrors) = getErrorMapAndExpectedCount(testSource.sourceFiles.toIndexedSeq) lazy val actualErrors = reporters.foldLeft(0)(_ + _.errorCount) lazy val (expected, unexpected) = getMissingExpectedErrors(errorMap, reporters.iterator.flatMap(_.errors)) @@ -871,8 +869,7 @@ trait ParallelTesting extends RunnerOrchestration { self => reporters.flatMap(_.allErrors.sortBy(_.pos.line).map(e => s"${e.pos.line + 1}: ${e.message}")).mkString(" at ", "\n at ", "") Option { - if compilerCrashed then s"Compiler crashed when compiling: ${testSource.title}" - else if actualErrors == 0 then s"\nNo errors found when compiling neg test $testSource" + if actualErrors == 0 then s"\nNo errors found when compiling neg test $testSource" else if expectedErrors == 0 then s"\nNo errors expected/defined in $testSource -- use // error or // nopos-error" else if expectedErrors != actualErrors then s"""|Wrong number of errors encountered when compiling $testSource From 1877e64fc347183409366582be644682a955110f Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 17 Oct 2023 10:26:59 +0100 Subject: [PATCH 2/4] Vulpix: Allow warn tests to have no warnings [Cherry-picked b84333234c3f2705824a4989edc5f7e86db1defa] --- compiler/test/dotty/tools/vulpix/ParallelTesting.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala index b9586faf01ce..925c9b4f4d5c 100644 --- a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala +++ b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala @@ -741,8 +741,6 @@ trait ParallelTesting extends RunnerOrchestration { self => s"""Compilation failed for: ${testSource.title} |$showDiagnostics |""".stripMargin.trim.linesIterator.mkString("\n", "\n", "") - else if obtCount == 0 then s"\nNo warnings found when compiling warn test $testSource" - else if expCount == 0 then s"\nNo warning expected/defined in $testSource -- use // warn" else if expCount != obtCount then s"""|Wrong number of warnings encountered when compiling $testSource |expected: $expCount, actual: $obtCount From 3cee2542686b3d21c14087327799e8c3795fc97b Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 17 Oct 2023 10:35:30 +0100 Subject: [PATCH 3/4] Vulpix: Skip empty lines [Cherry-picked 372e48595d341186e2e6d6b1f20294c2c5adfe7a] --- compiler/test/dotty/tools/vulpix/ParallelTesting.scala | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala index 925c9b4f4d5c..8d07002ac620 100644 --- a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala +++ b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala @@ -733,9 +733,10 @@ trait ParallelTesting extends RunnerOrchestration { self => lazy val (map, expCount) = getWarnMapAndExpectedCount(testSource.sourceFiles.toIndexedSeq) lazy val obtCount = reporters.foldLeft(0)(_ + _.warningCount) lazy val (expected, unexpected) = getMissingExpectedWarnings(map, reporters.iterator.flatMap(_.diagnostics)) + lazy val diagnostics = reporters.flatMap(_.diagnostics.toSeq.sortBy(_.pos.line).map(e => s" at ${e.pos.line + 1}: ${e.message}")) + def showLines(title: String, lines: Seq[String]) = if lines.isEmpty then "" else title + lines.mkString("\n", "\n", "") def hasMissingAnnotations = expected.nonEmpty || unexpected.nonEmpty - def showDiagnostics = "-> following the diagnostics:\n" + - reporters.flatMap(_.diagnostics.toSeq.sortBy(_.pos.line).map(e => s"${e.pos.line + 1}: ${e.message}")).mkString(" at ", "\n at ", "") + def showDiagnostics = showLines("-> following the diagnostics:", diagnostics) Option: if reporters.exists(_.errorCount > 0) then s"""Compilation failed for: ${testSource.title} @@ -744,8 +745,8 @@ trait ParallelTesting extends RunnerOrchestration { self => else if expCount != obtCount then s"""|Wrong number of warnings encountered when compiling $testSource |expected: $expCount, actual: $obtCount - |${expected.mkString("Unfulfilled expectations:\n", "\n", "")} - |${unexpected.mkString("Unexpected warnings:\n", "\n", "")} + |${showLines("Unfulfilled expectations:", expected)} + |${showLines("Unexpected warnings:", unexpected)} |$showDiagnostics |""".stripMargin.trim.linesIterator.mkString("\n", "\n", "") else if hasMissingAnnotations then s"\nWarnings found on incorrect row numbers when compiling $testSource\n$showDiagnostics" From 9cd5fc24f5fe4312b46ff41a7ca85c368e18cc79 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 17 Oct 2023 10:41:00 +0100 Subject: [PATCH 4/4] Fix unreachable warning in deeply nested sealed hierarchy Without applying we were constructing the type Jacket#Body, instead of Jacket[?]#Body, which lead down to an incorrect isSubSpace calculation and thus an unreachable warning. [Cherry-picked 9460b7d4fb8c2e7ee197831b76d458f2f67cbf71] --- .../src/dotty/tools/dotc/core/TypeOps.scala | 2 +- tests/warn/i18661.scala | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 tests/warn/i18661.scala diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala index 6809e4b9083c..6478e7332e4b 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala @@ -883,7 +883,7 @@ object TypeOps: else if symbol.is(Module) then TermRef(this(tref.prefix), symbol.sourceModule) else if (prefixTVar != null) - this(tref) + this(tref.applyIfParameterized(tref.typeParams.map(_ => WildcardType))) else { prefixTVar = WildcardType // prevent recursive call from assigning it // e.g. tests/pos/i15029.more.scala, create a TypeVar for `Instances`' B, so we can disregard `Ints` diff --git a/tests/warn/i18661.scala b/tests/warn/i18661.scala new file mode 100644 index 000000000000..b7f490ae44df --- /dev/null +++ b/tests/warn/i18661.scala @@ -0,0 +1,28 @@ +class Jacket[T]: + sealed trait BodyType: + sealed trait OrganType: + case class Heart() extends Body.Organ + case class Brain() extends Body.Organ + object Organ extends OrganType + sealed trait Organ + object Body extends BodyType + sealed trait Body + +type AnyJacket = Jacket[?] +type AnyBodyOrgan = AnyJacket#BodyType#Organ +type AnyBodyOrganHeart = AnyJacket#BodyType#OrganType#Heart +type AnyBodyOrganBrain = AnyJacket#BodyType#OrganType#Brain + +def check( asr : AnyBodyOrgan ) : String = + asr match + case c : AnyBodyOrganHeart => "Heart" + case s : AnyBodyOrganBrain => "Brain" // was: unreachable + +val jacket = new Jacket[Unit] +val heart = new jacket.Body.Organ.Heart() +val brain = new jacket.Body.Organ.Brain() + +@main +def go = + println( check( heart ) ) + println( check( brain ) )