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

route file compilation warning ("-Ywarn-unused"): local val in method at is never used #6302

Open
pedrorijo91 opened this issue Jul 6, 2016 · 22 comments

Comments

@pedrorijo91
Copy link
Contributor

pedrorijo91 commented Jul 6, 2016

Play Version (2.5.4 / 2.4.3 / 2.4.6 - not tested on other versions) - scala

Operating System (MacOS 10.10 - and probably all other OS's)

JDK (Oracle 1.8.0_72, OpenJDK 1.8.x, Azul Zing)

$ java -version
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)

Behaviour

On my play app, I have a routes file with routes for public files. Recently I added the -Ywarn-unused compiler flag, and I'm getting some unexpected warnings.

GET        /favicon.ico controllers.Assets.at(path="/public",file="/images/favicon.ico")

GET        /favicon.png controllers.Assets.at(path="/public",file="/images/favicon.png")

GET        /robots.txt             controllers.Assets.at(path="/public",file="robots.txt")
$ sbt compile
[info] Loading project definition from /Users/pedrorijo/git/testRepos/testingScalac/project
[info] Set current project to testingScalac (in build file:/Users/pedrorijo/git/testRepos/testingScalac/)
[info] Compiling 4 Scala sources and 1 Java source to /Users/pedrorijo/git/testRepos/testingScalac/target/scala-2.11/classes...
[warn] /Users/pedrorijo/git/testRepos/testingScalac/conf/routes:15: local val in method at is never used
[warn] GET        /favicon.ico            controllers.Assets.at(path="/public",file="/images/favicon.ico")
[warn] /Users/pedrorijo/git/testRepos/testingScalac/conf/routes:16: local val in method at is never used
[warn] GET        /favicon.png            controllers.Assets.at(path="/public",file="/images/favicon.png")
[warn] /Users/pedrorijo/git/testRepos/testingScalac/conf/routes:17: local val in method at is never used
[warn] GET        /robots.txt             controllers.Assets.at(path="/public",file="robots.txt")
[warn] three warnings found
[success] Total time: 10 s, completed Jul 5, 2016 3:11:28 PM

Reproducible Test Case

  1. activator new testingScalac (choose play-scala from the template list)
  2. Add to build.sbt the flag with scalacOptions ++= Seq("-Ywarn-unused")
  3. Add to the routes file:
GET        /favicon.ico controllers.Assets.at(path="/public",file="/images/favicon.ico")

GET        /favicon.png controllers.Assets.at(path="/public",file="/images/favicon.png")

GET        /robots.txt             controllers.Assets.at(path="/public",file="robots.txt")

Am I doing something wrong on the routes file, or is it a playframework/compiler bug (I looked in github and couldn't find anything related to this)?

@gmethvin
Copy link
Member

gmethvin commented Jul 7, 2016

This might be related to SI-9158. If you look at the generated code, it seems like all the vals are being used.

@meddulla
Copy link

Looking at the generated code in routes/main/controllers/ReverseRoutes.scala (method at) the culprit might be the implicit value

implicit val _rrc = new ReverseRouteContext(Map(("path", "/public"), ("file", "images/favicon.ico")))
         
 Call("GET", _prefix + { _defaultPrefix } + "favicon.ico")

even though it is being used..

@mkurz
Copy link
Member

mkurz commented Apr 19, 2017

This might be related to SI-9158. If you look at the generated code, it seems like all the vals are being used.

SI-9158 has been fixed in Scala 2.12.2. Ref.: #7250

@mkurz
Copy link
Member

mkurz commented Apr 27, 2017

The warnings still occur - I just tested with Play 2.6.0-M5 which uses Scala 2.12.2 - even though SI-9158 is fixed now. Seems like we have to wait even longer until this gets addressed in Scala.
I pushed a test project which prints the warnings when running sbt clean compile:
https://github.com/mkurz/play-route-file-warnings

@michaelahlers
Copy link

Having an identical experience to @mkurz's.

@marcospereira
Copy link
Member

@mkurz and @michaelahlers can you confirm this is still happening with RC2, after #7259?

@mkurz
Copy link
Member

mkurz commented Jun 22, 2017

@marcospereira Still getting the warning using this test project https://github.com/mkurz/play-route-file-warnings:

[warn] play-route-file-warnings/conf/routes:6: local val _rrc in method at is never used
[warn] GET        /favicon.ico controllers.Assets.at(path="/public",file="/images/favicon.ico")
[warn] play-route-file-warnings/conf/routes:8: local val _rrc in method at is never used
[warn] GET        /favicon.png controllers.Assets.at(path="/public",file="/images/favicon.png")
[warn] play-route-file-warnings/conf/routes:10: local val _rrc in method at is never used
[warn] GET        /robots.txt             controllers.Assets.at(path="/public",file="robots.txt")
[warn] play-route-file-warnings/conf/routes:6: pattern var params in method applyOrElse is never used; `params@_' suppresses this warning
[warn] GET        /favicon.ico controllers.Assets.at(path="/public",file="/images/favicon.ico")
[warn] play-route-file-warnings/conf/routes:8: pattern var params in method applyOrElse is never used; `params@_' suppresses this warning
[warn] GET        /favicon.png controllers.Assets.at(path="/public",file="/images/favicon.png")
[warn] play-route-file-warnings/conf/routes:10: pattern var params in method applyOrElse is never used; `params@_' suppresses this warning
[warn] GET        /robots.txt             controllers.Assets.at(path="/public",file="robots.txt")
[warn] 6 warnings found

@wsargent
Copy link
Member

wsargent commented Jun 29, 2017

Fixed half of them with #7538 -- the implicit

local val _rrc in method at is never used
[warn] GET        /robots.txt             controllers.Assets.at(path="/public",file="robots.txt")

are coming from


        // @LINE:8
        case (file) if file == "/images/favicon.png" =>
          implicit val _rrc = new play.core.routing.ReverseRouteContext(Map(("path", "/public"), ("file", "/images/favicon.png")))
          Call("GET", _prefix + { _defaultPrefix } + "favicon.png")

which is from https://github.com/playframework/playframework/blob/master/framework/src/routes-compiler/src/main/twirl/play/routes/compiler/static/reverseRouter.scala.twirl#L26

and the reverseRoutesContext call itself is https://github.com/playframework/playframework/blob/master/framework/src/routes-compiler/src/main/scala/play/routes/compiler/templates/package.scala#L236

So it's possible to remove the implicit val by collapsing reverseRouter.scala.twirl into a single line with an explicit import, but I'd far rather mark this with an annotation saying that the compiler should ignore the "unused" flag here.

@wsargent
Copy link
Member

As far as I can tell, there is not an annotation or a flag option to ignore a line of code, or to suppress unused checks in a package or file. Closest I can find is scala/bug#7934

@wsargent
Copy link
Member

There is the option of running the generated code through scalafix (which would remove unused imports but not the implicit vals) or setting up a subproject which contained twirl code and then passing through the binary dependency... but those are hacks.

The best answer I can give right now is to use the routing DSL, which uses macros internally and so isn't exposed to scala flags in the same way.

@godenji
Copy link
Contributor

godenji commented Aug 26, 2017

This is pretty unfortunate, with -Xfatal-warnings it's impossible to enable warnings on unused imports (since the warnings can't be fixed in user code).

@wsargent
Copy link
Member

@godenji see https://github.com/ghik/silencer as a possible option

@zgrannan
Copy link
Contributor

The only use of ReverseRoutingContext (which is the type of _rrc) I could find is here:

private def pathFromParams(rrc: ReverseRouteContext): String = {

and it looks to me like it's only current purpose is to handle a specific case of adding a path variable for Asset routing. Since the _rrc variable is introduced for every route that has fixed parameters (not just this specific case), it would be unused in the general case.

It seems to me like only introducting _rrc for the specific case of asset routing would get rid of the unused variable warning. I think that doing the following could work:

  • Change the definition of the ReverseRouteContext class to: ReverseRouteContext(path: String)
  • Only introduce _rrc if there is a fixed path parameter of type String, and another parameter of type Asset

Does this seem like a workable approach?

@zgrannan
Copy link
Contributor

Since it wasn't too much work, I implemented something similar to the above here: #7838. It doesn't change the definition of ReverseRouteContext in order to maintain binary compatibility.

@som-snytt
Copy link

They added @annotation.unused for definitions but -Wconf (aka silencer) for misc warnings such as unused imports. Also @nowarn.

@mkurz
Copy link
Member

mkurz commented May 6, 2020

For reference: scala/scala#8373

@mkurz mkurz added this to the 2.9.0 milestone Mar 25, 2021
@gmethvin
Copy link
Member

gmethvin commented Feb 2, 2023

Generally I add the following to scalacOptions:

  "-Wconf:cat=unused&src=routes/.*:s", // silence unused errors in generated routes files
  "-Wconf:cat=unused&src=twirl/.*:s", // silence unused errors in generated twirl template files

So one possibility is to automate adding these options in some way, or at least make it easy for users to mix that into their existing scala compiler options. One caveat here is that if Play adds to scalacOptions initially, then users' settings can override the ones Play sets.

We might also explore using @nowarn in the generated code, which might be more robust.

@mkurz
Copy link
Member

mkurz commented Mar 9, 2023

@mkurz mkurz modified the milestones: 2.9.0, 2.10.0 May 19, 2023
@markusphil
Copy link

Has anyone experiences in working around this with Play3 and Scala3?

Since the src (and also the site) filter is not (yet) available in Scala 3, the solution proposed by @gmethvin is not working. We relied on matching the msg for the unused _rrc variable. But this is not possible for unused imports in the generate routes file, since the msg there is just "unused import".

@mkurz
Copy link
Member

mkurz commented Dec 19, 2023

Has anyone experiences in working around this with Play3 and Scala3?

Yes, see https://www.youtube.com/watch?v=4EUpiCTVM1c&t=999s 😉

You probably have to wait for

Hopefully it's merged and released soon 😉

@henricook have you come up with a workaround (I see you commented in scala/scala3#18782)

@henricook
Copy link
Contributor

Thanks for the tag @mkurz. I was using sbt-tpolecat for warnings as errors and found this blocking as a result. Seeing the scala ticket you've linked I decided to relax my warnings-as-errors requirement until it was released. This is fine for me on a brand new side project but I appreciate it won't be ideal for anyone with an existing project.

plugins.sbt:

// SBT tpolecat - compiler defaults
// Add once https://github.com/lampepfl/dotty/issues/18782 is merged and uncomment scalaCOption in build.sbt
// addSbtPlugin("org.typelevel" % "sbt-tpolecat" % "0.5.0")

@som-snytt
Copy link

Also on Scala 2, unused import warning has an "origin" corresponding to the import selector.

scala 2.13.12> { import concurrent.*; 42 }
                                   ^
               warning: Unused import
val res0: Int = 42

but

$ scala -Wconf:origin=scala.concurrent:s -Xsource:3
scala 2.13.12> { import concurrent.*; 42 }
val res0: Int = 42

scala 2.13.12>

That tweak was specifically because a top-level import isn't amenable to nowarn.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 🆕 New
Development

No branches or pull requests