Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@nowarn annotations behavior change between 0.5.0 and 0.5.1 #210

Closed
jacbop opened this issue Apr 11, 2024 · 3 comments
Closed

@nowarn annotations behavior change between 0.5.0 and 0.5.1 #210

jacbop opened this issue Apr 11, 2024 · 3 comments

Comments

@jacbop
Copy link

jacbop commented Apr 11, 2024

In version 0.5.0, we were able to suppress unused value warnings in scalacheck tests like so:

package com.test

import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
import scala.annotation.nowarn

@nowarn("msg=unused value of type org.scalatest.Assertion")
class MainSpec extends AnyFreeSpec with Matchers {
  "unused value warnings" in {
    "3".toInt shouldBe 3
    "4".toInt shouldBe 4
  }
}

This complies and runs with 0.5.0 of the plugin, but under version 0.5.1 we see the following compiler error:

➜  test [error] -- [E176] Potential Issue Error: /Users/twilberding/test/src/test/scala/MainSpec.scala:10:4
[error] 10 |    "3".toInt shouldBe 3
[error]    |    ^^^^^^^^^^^^^^^^^^^^
[error]    |    unused value of type org.scalatest.Assertion
[error] one error found
[error] (Test / compileIncremental) Compilation failed

I see from the README that we can disable this in built.sbt with Test / tpolecatExcludeOptions += ScalacOptions.warnNonUnitStatement

But we have many projects that are suppressing on a per file basis via annotations.
Is this a regression issue or a desired functionality change between 0.5.0 and 0.5.1?

@jacbop
Copy link
Author

jacbop commented Apr 11, 2024

Here is my build.sbt

import Dependencies.*
import org.typelevel.scalacoptions.ScalacOptions
import sbt.Keys.libraryDependencies

val scalaV = "3.3.3"

val commonSettings = Seq(
  scalaVersion := scalaV,
  organization := "com.test",
  scalacOptions ++= Seq("-no-indent"),
  tpolecatScalacOptions += ScalacOptions.sourceFuture,
  libraryDependencies ++= coreLibraries,
  libraryDependencies ++= testLibraries
)

lazy val root: Project = (project in file("."))
  .settings(
    name                := "test-app",
    Compile / mainClass := Some("com.test.Main"),
    commonSettings,
    run / fork          := true
  )
  .enablePlugins(JavaAppPackaging)

my plugins.sbt config

addSbtPlugin("org.typelevel"  % "sbt-tpolecat"        % "0.5.1")  //Adds useful compiler warnings
addSbtPlugin("org.scalameta"  % "sbt-scalafmt"        % "2.5.2")  //Formats code
addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.9.16") //Allows distributing your app

and my dependencies

import sbt._

object Dependencies {
  // Core deps
  val catsEffectV     = "3.5.4"
  val catsV           = "2.10.0"

  // Test deps
  val scalaCheckV          = "1.17.0"
  val scalaTestScalacheckV = "3.2.18.0"
  val scalaTestV           = "3.2.18"

  lazy val coreLibraries = Seq(
    "org.typelevel"       %% "cats-core"                % catsV,
    "org.typelevel"       %% "cats-effect"              % catsEffectV // Concurrency and Pure FP
  )

  lazy val testLibraries = Seq(
    "org.scalacheck"    %% "scalacheck"       % scalaCheckV          % Test,
    "org.scalatest"     %% "scalatest"        % scalaTestV           % Test,
    "org.scalatestplus" %% "scalacheck-1-17"  % scalaTestScalacheckV % Test
  )

}

@TonioGela
Copy link
Member

TonioGela commented Apr 12, 2024

Is this a regression issue or a desired functionality change between 0.5.0 and 0.5.1?

This flag got in by default when updating typelevel/scalac-options and I'm prone to say that is a desired functionality, as in general, it warns you when you forget unused stuff, i.e.

//> using scala 3.4.1
//> using toolkit typelevel::latest
//> using option -Wnonunit-statement

import cats.effect.*

object Main extends IOApp.Simple:
  def run: IO[Unit] =
    IO.pure("discarded") // <-- you'll get a warn here
    IO.println("foo") *> IO.println("bar")

As per your case, I'll try to reproduce it with sbt, as with scala-cli it doesn't appear to be faulty:

//> using scala 3.3.3
//> using dep org.scalatest::scalatest::3.2.18
//> using option -Wnonunit-statement, -Wunused:nowarn

import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
import scala.annotation.nowarn

@nowarn("msg=unused value of type org\\.scalatest\\.Assertion")
class MainSpec extends AnyFreeSpec with Matchers:
  "unused value warnings" in {
    "3".toInt shouldBe 3
    "4".toInt shouldBe 4
  }

A thing to bear in mind is that the syntax for nowarn is @nowarn("msg=<regex>") so theoretically you might want to escape the dots if you're planning to match against the exact string (i.e. @nowarn("msg=unused value of type org\\.scalatest\\.Assertion"))
Also, I suggest you using -Wunused:nowarn for debug, so that you might get a warn even when a nowarn gets unused (maybe because the regex isn't matching).

@TonioGela
Copy link
Member

As @Daenyth made me notice, this is probably related to a 3.3.x bug: scala/scala3#18804.
Apparently updating to 3.4.1 seems to be the only fix apart for: #134 (comment).
See further details here: https://gist.github.com/Daenyth/a008964c61b1740974767b833064cc5e

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants