Skip to content

-Wunused:explicits false negative for a method parameter in some cases #17742

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

Closed
ruurtjan opened this issue May 31, 2023 · 4 comments
Closed
Assignees
Labels
area:linting Linting warnings enabled with -W or -Xlint itype:bug

Comments

@ruurtjan
Copy link

ruurtjan commented May 31, 2023

Edit: see @mrdziuban's comment for clarification

The following reproducer flags a used parameter as unused. Changing any of the following will cause the compilation to succeed:

  1. Remove the private keyword
  2. Remove val baz = and baz

Compiler version

Tested on 3.3.0 and 3.3.1-RC1

Minimized code

object Reproducer extends App {
  
  private def foo(bar: Int) = {
    val baz = 1 match
      case bar => "hello"
    baz
  }

  println(foo(1))
}
Global / scalaVersion := "3.3.0"

scalacOptions ++= Seq(
  "-Xfatal-warnings",
  "-Wunused:explicits",
)

Output

[error] 3 |  private def foo(bar: Int) = {
[error]   |                  ^^^
[error]   |                  unused explicit parameter

Expectation

Compile without warning.

@ruurtjan ruurtjan added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels May 31, 2023
@mrdziuban
Copy link

I believe some of the compiler's behavior here is correct @ruurtjan -- case bar => "hello" isn't matching against the existing variable named bar, it's binding a new pattern variable named bar. To do the former you'd need to wrap it in backticks. The issue can be demonstrated by calling foo with any Int other than 1 and seeing that it still returns "hello"

def foo1(bar: Int) = {
  val baz = 1 match
    case bar => "hello"
  baz
}

foo1(2)
// "hello"

// Now using backticks
def foo2(bar: Int) = {
  val baz = 1 match
    case `bar` => "hello"
  baz
}

foo2(2)
// scala.MatchError...

However this still doesn't explain why removing private or val baz causes the unused warning to disappear...

@jchyb jchyb added area:linting Linting warnings enabled with -W or -Xlint and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels May 31, 2023
@jchyb jchyb changed the title -Wunused:explicits incorrectly flags function parameter in some cases -Wunused:explicits false negative for a method parameter in some cases May 31, 2023
@som-snytt
Copy link
Contributor

Scala 2.13.12 will lint the pattern var shadowing the definition in scope; it caught a test that wasn't testing anything, so it happens.

Hopefully Scala 3 will also get the lint.

@ruurtjan
Copy link
Author

ruurtjan commented Jun 1, 2023

Ah, you're right @mrdziuban! In that case, upgrading to 3.3.0 and enabling -Wunused:explicits already caught a bug in my code :)

I'll leave this issue open for the false negative issue.

@szymon-rd
Copy link
Contributor

It's the expected behaviour. Removing private makes it a public definition, and these are not checked for usage of their parameters - they may be introduced for inheritance, matching definitions, or other reasons. Similarly, methods with trivial bodies are not reported, as the intent in these cases is often to provide a dummy definition. What is missing however is a strict definition of trivial bodies, see: #16640

@szymon-rd szymon-rd closed this as not planned Won't fix, can't repro, duplicate, stale Aug 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:linting Linting warnings enabled with -W or -Xlint itype:bug
Projects
None yet
Development

No branches or pull requests

5 participants