Skip to content

Show parameter type in -Wunused:params warnings#10014

Closed
benrbray wants to merge 1 commit intoscala:2.13.xfrom
benrbray:unused-param-show-type
Closed

Show parameter type in -Wunused:params warnings#10014
benrbray wants to merge 1 commit intoscala:2.13.xfrom
benrbray:unused-param-show-type

Conversation

@benrbray
Copy link
Copy Markdown

@benrbray benrbray commented Apr 24, 2022

I recently filed scalameta/metals-feature-requests#270 and learned that the unused parameter warnings in Metals are forwarded from scalac. I realized it would only be a relatively minor change to the compiler, so I'd like to get the ball rolling with this PR.

Problem

Currently, unused named parameters give the following warning. The type is not shown, but having the name available makes it easy to figure out which parameter is unused.

// parameter value arg in method unusedParam is never used
def unusedParam(arg: Int): Unit = { }

// parameter value arg in method unusedParam is never used
def unusedImplicit(implicit arg: Int): Unit = { }

However, when using context bounds, implicit arguments have auto-generated names like evidence$1, making it difficult to identify the steps needed to resolve the warning, especially in cases where there are several type parameters each with their own context bounds.

object UnusedExample {

  abstract class Foo[T] {
    def foo(arg: T): Unit
  }
  abstract class Bar[T] {
    def bar(arg: T): Unit
  }

  // parameter value evidence$2 in method useFoo is never used
  def unusedFoo[A: Foo: Bar](a: A): Unit = {
    val foo = implicitly[Foo[A]]
    foo.foo(a)
  }
}

Proposed Solution

Warning messages generated by -Wunused:params should include both the name AND type of the unused parameter. For example,

// parameter value arg in method unusedParam is never used
// Type: Int
def unusedParam(arg: Int): Unit = { }

// parameter value `arg: Int` in method unusedParam is never used
// Type: Int
def unusedImplicit(implicit arg: Int): Unit = { }
object UnusedExample {

  abstract class Foo[T] {
    def foo(arg: T): Unit
  }
  abstract class Bar[T] {
    def bar(arg: T): Unit
  }

  // parameter value evidence$2 in method useFoo is never used
  // Type: Bar[A]
  def unusedFoo[A: Foo: Bar](a: A): Unit = {
    val foo = implicitly[Foo[A]]
    foo.foo(a)
  }
}

Alternatives

Without these more descriptive error messages, the only way to identify the source of an unused evidence$n warning is to count up to the nth context bound in the method signature.

In certain cases, the squiggly red/yellow underline will be drawn directly under the unused context bound, making it easy to see which context bound is unused. However, in some cases it will be drawn under the method name itself (which is probably a bug, although I was not able to reproduce it for my simple example).

Questions

  1. What is the clearest / least intrusive way to present the type information? I chose to display it on a new line, which may be better for longer type signatures. Alternatively, the type could appear adjacent to the argument name. Open to suggestions.
  2. For consistency, should the other -Wunused warnings be updated to show type information as well?

I'm happy to do the work on this after receiving some guidance on the above.

Todos

  • once the specific language for the warning(s) has been chosen, update the test cases to reflect the expected warning messages

@scala-jenkins scala-jenkins added this to the 2.13.9 milestone Apr 24, 2022
)
for (s <- unusedPrivates.unusedParams if warnable(s))
emitUnusedWarning(s.pos, s"parameter $s in ${if (s.owner.isAnonymousFunction) "anonymous function" else s.owner} is never used", WarningCategory.UnusedParams, s)
emitUnusedWarning(s.pos, s"parameter $s in ${if (s.owner.isAnonymousFunction) "anonymous function" else s.owner} is never used\nType: ${s.tpe.toLongString}", WarningCategory.UnusedParams, s)
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is toLongString the best way to show complete type information here? or nameAndArgsString?

@SethTisue SethTisue modified the milestones: 2.13.9, 2.13.10 Apr 25, 2022
@som-snytt
Copy link
Copy Markdown
Contributor

I fixed the position in #10015 and then also included different words for evidence. I'm not sure the extra info in the message is necessary, but it probably could not hurt.

@SethTisue
Copy link
Copy Markdown
Member

@benrbray thanks for getting the ball rolling here! we've now merged the successor PR (#10015)

@SethTisue SethTisue closed this May 12, 2022
@SethTisue SethTisue removed this from the 2.13.10 milestone May 12, 2022
@benrbray benrbray deleted the unused-param-show-type branch May 13, 2022 01:41
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

Successfully merging this pull request may close these issues.

4 participants