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

-Ywarn-unused warns for vals in for comprehension,"local val... is never used" #9158

Closed
scabug opened this issue Feb 17, 2015 · 6 comments
Closed
Assignees
Milestone

Comments

@scabug
Copy link

scabug commented Feb 17, 2015

$ cat unused.scala
object Unused {
  val optTup = Some((1, 2))

  for {
    tup <- optTup
    (num1, num2) = tup
  } yield (num1 + num2)
}
$ scalac -Ywarn-unused unused.scala
unused.scala:6: warning: local val in value $anonfun is never used
    (num1, num2) = tup
     ^
unused.scala:6: warning: local val in value $anonfun is never used
    (num1, num2) = tup
           ^
two warnings found
@scabug
Copy link
Author

scabug commented Feb 17, 2015

Imported From: https://issues.scala-lang.org/browse/SI-9158?orig=1
Reporter: Andrey Kuznetsov (prettynatty)
Affected Versions: 2.11.5
See #7712

@scabug
Copy link
Author

scabug commented Feb 18, 2015

@retronym said:
We removed this option from -Xlint in #7712 because, as you have found, it is somewhat incomplete.

@scabug
Copy link
Author

scabug commented Feb 18, 2015

@som-snytt said:
One way to look at it is that the warning is there to keep you from doing something unintentional.

The warning is not spurious, in that the for comprehension desugars into an extra packaging step; it's the for comprehension equivalent of autoboxing.

http://stackoverflow.com/questions/14087014/what-are-the-scoping-rules-for-vals-in-scala-for-comprehensions

See the part where he goes, "Wait, really?" The locals in the yield block are unused.

http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#for-comprehensions-and-for-loops

Intended:

  for {
    tup <- optTup
  } yield {
    val (num1, num2) = tup
    (num1 + num2)
  }

@scabug
Copy link
Author

scabug commented Feb 18, 2015

Andrey Kuznetsov (prettynatty) said (edited on Feb 18, 2015 9:55:45 PM UTC):
But what if I want to write the something like this? Such code throws warning too.

  for {
    tup1 <- optTup
    (num1, num2) = tup1
    tup2 <- fn(num2, num1)
  } yield {
    tup2 // or anything else
  }

Is it really unintended?

@scabug
Copy link
Author

scabug commented Sep 6, 2015

@som-snytt said:
Here is another example that could benefit from more efficient handling of intermediate results.

Because the unused extraction result i is not bundled in the tupling step, the extractor is invoked three times.

scala> for (s <- List("ab","abc") ; X(i) = s if i > 2) yield i // show
[snip]
      val res0 = List("ab", "abc").map(((s) => {
        <synthetic> <artifact> private[this] val x$2 = s: @scala.unchecked match {
          case (x$1 @ X((i @ _))) => scala.Tuple2(x$1, i)
        };
        val x$1 = x$2._1;
        val i = x$2._2;
        scala.Tuple2(s, x$1)
      })).withFilter(((x$3) => x$3: @scala.unchecked match {
        case scala.Tuple2((s @ _), X((i @ _))) => i > 2
      })).map(((x$4) => x$4: @scala.unchecked match {
        case scala.Tuple2((s @ _), X((i @ _))) => i
      }))
    }
  }
}

@scabug
Copy link
Author

scabug commented Sep 15, 2016

@som-snytt said:
The PR tags the binds as if they were (i @ *, j @ *) = t which is the way to disable the warning in source.

scala/scala#5402

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

No branches or pull requests

3 participants