Skip to content

Commit

Permalink
Merge pull request #10150 from som-snytt/issue/12495-lint-discarded-args
Browse files Browse the repository at this point in the history
  • Loading branch information
SethTisue committed Nov 29, 2022
2 parents fd4fe90 + 6c530ac commit bce7748
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 4 deletions.
2 changes: 2 additions & 0 deletions src/compiler/scala/tools/nsc/settings/Warnings.scala
Expand Up @@ -213,6 +213,7 @@ trait Warnings {
val MultiargInfix = LintWarning("multiarg-infix", "Infix operator was defined or used with multiarg operand.")
val ImplicitRecursion = LintWarning("implicit-recursion", "Implicit resolves to an enclosing definition.")
val UniversalMethods = LintWarning("universal-methods", "Require arg to is/asInstanceOf.")
val ArgDiscard = LintWarning("arg-discard", "-Wvalue-discard for adapted arguments.")

def allLintWarnings = values.toSeq.asInstanceOf[Seq[LintWarning]]
}
Expand Down Expand Up @@ -246,6 +247,7 @@ trait Warnings {
def multiargInfix = lint contains MultiargInfix
def lintImplicitRecursion = lint.contains(ImplicitRecursion) || (warnSelfImplicit.value: @nowarn("cat=deprecation"))
def lintUniversalMethods = lint.contains(UniversalMethods)
def lintArgDiscard = lint.contains(ArgDiscard)

// The Xlint warning group.
val lint = MultiChoiceSetting(
Expand Down
16 changes: 12 additions & 4 deletions src/compiler/scala/tools/nsc/typechecker/Adaptations.scala
Expand Up @@ -77,20 +77,28 @@ trait Adaptations {
)
}
@inline def msg(what: String): String = s"adaptation of an empty argument list by inserting () $what"
@inline def noAdaptation = {
@inline def noAdaptation: false = {
context.error(t.pos, adaptWarningMessage(msg("has been removed"), showAdaptation = false))
false // drop adaptation
}
@inline def deprecatedAdaptation = {
@inline def deprecatedAdaptation: true = {
val twist =
if (isLeakyTarget) "leaky (Object-receiving) target makes this especially dangerous"
else "this is unlikely to be what you want"
val text = s"${msg("is deprecated")}: ${twist}"
context.deprecationWarning(t.pos, t.symbol, adaptWarningMessage(text), "2.11.0")
true // keep adaptation
}
@inline def warnAdaptation = {
if (settings.warnAdaptedArgs && !isInfix) context.warning(t.pos, adaptWarningMessage(
@inline def warnAdaptation: true = {
def discardedArgs = t match {
case Apply(_, stat @ Block(Apply(TypeApply(Select(adapter, _), _), adapted) :: Nil, expr) :: Nil) =>
isTupleSymbol(adapter.symbol.companion) && expr.tpe == UnitTpe && adapted == args
case _ => false
}
if (settings.lintArgDiscard && discardedArgs) context.warning(t.pos, adaptWarningMessage(
s"adapted the argument list to expected Unit type: arguments will be discarded"),
WarningCategory.LintAdaptedArgs)
else if (settings.warnAdaptedArgs && !isInfix) context.warning(t.pos, adaptWarningMessage(
s"adapted the argument list to the expected ${args.size}-tuple: add additional parens instead"),
WarningCategory.LintAdaptedArgs)
true // keep adaptation
Expand Down
12 changes: 12 additions & 0 deletions test/files/neg/t12495.check
@@ -0,0 +1,12 @@
t12495.scala:4: warning: discarded non-Unit value of type (Int, Int)
def g = f(42, 27)
^
t12495.scala:4: warning: adapted the argument list to expected Unit type: arguments will be discarded
signature: Function1.apply(v1: T1): R
given arguments: 42, 27
after adaptation: Function1((42, 27): Unit)
def g = f(42, 27)
^
error: No warnings can be incurred under -Werror.
2 warnings
1 error
5 changes: 5 additions & 0 deletions test/files/neg/t12495.scala
@@ -0,0 +1,5 @@
// scalac: -Werror -Xlint:arg-discard,adapted-args -Wvalue-discard
class C {
val f = (u: Unit) => println(s"[$u]")
def g = f(42, 27)
}

0 comments on commit bce7748

Please sign in to comment.