Skip to content

Backport "Disable WUnused for params of non-private defs" #17280

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

Merged
merged 5 commits into from
Apr 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions compiler/src/dotty/tools/dotc/transform/CheckUnused.scala
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ class CheckUnused private (phaseMode: CheckUnused.PhaseMode, suffix: String, _ke

override def prepareForDefDef(tree: tpd.DefDef)(using Context): Context =
unusedDataApply{ ud =>
if !tree.symbol.is(Private) then
tree.termParamss.flatten.foreach { p =>
ud.addIgnoredParam(p.symbol)
}
import ud.registerTrivial
tree.registerTrivial
traverseAnnotations(tree.symbol)
Expand Down Expand Up @@ -350,6 +354,8 @@ object CheckUnused:
/** Trivial definitions, avoid registering params */
private val trivialDefs = MutSet[Symbol]()

private val paramsToSkip = MutSet[Symbol]()

/**
* Push a new Scope of the given type, executes the given Unit and
* pop it back to the original type.
Expand Down Expand Up @@ -396,6 +402,8 @@ object CheckUnused:
def removeIgnoredUsage(sym: Symbol)(using Context): Unit =
doNotRegister --= sym.everySymbol

def addIgnoredParam(sym: Symbol)(using Context): Unit =
paramsToSkip += sym

/** Register an import */
def registerImport(imp: tpd.Import)(using Context): Unit =
Expand All @@ -410,8 +418,9 @@ object CheckUnused:
if memDef.isValidMemberDef then
if memDef.isValidParam then
if memDef.symbol.isOneOf(GivenOrImplicit) then
implicitParamInScope += memDef
else
if !paramsToSkip.contains(memDef.symbol) then
implicitParamInScope += memDef
else if !paramsToSkip.contains(memDef.symbol) then
explicitParamInScope += memDef
else if currScopeType.top == ScopeType.Local then
localDefInScope += memDef
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ trait InterFace {
}

trait BadAPI extends InterFace {
def f(a: Int,
private def f(a: Int,
b: String, // error
c: Double): Int = {
println(c)
Expand All @@ -33,7 +33,7 @@ trait BadAPI extends InterFace {

override def equals(other: Any): Boolean = true // OK

def i(implicit s: String) = answer // error
def i(implicit s: String) = answer // ok

/*
def future(x: Int): Int = {
Expand Down Expand Up @@ -63,7 +63,7 @@ case class CaseyKasem(k: Int) // OK
case class CaseyAtTheBat(k: Int)(s: String) // ok

trait Ignorance {
def f(readResolve: Int) = answer // error
def f(readResolve: Int) = answer // ok
}

class Reusing(u: Int) extends Unusing(u) // OK
Expand All @@ -78,28 +78,28 @@ trait Unimplementation {
}

trait DumbStuff {
def f(implicit dummy: DummyImplicit) = answer // todo // error
def g(dummy: DummyImplicit) = answer // error
def f(implicit dummy: DummyImplicit) = answer // ok
def g(dummy: DummyImplicit) = answer // ok
}
trait Proofs {
def f[A, B](implicit ev: A =:= B) = answer // todo // error
def g[A, B](implicit ev: A <:< B) = answer // todo // error
def f2[A, B](ev: A =:= B) = answer // error
def g2[A, B](ev: A <:< B) = answer // error
def f[A, B](implicit ev: A =:= B) = answer // ok
def g[A, B](implicit ev: A <:< B) = answer // ok
def f2[A, B](ev: A =:= B) = answer // ok
def g2[A, B](ev: A <:< B) = answer // ok
}

trait Anonymous {
def f = (i: Int) => answer // error
def f = (i: Int) => answer // ok

def f1 = (_: Int) => answer // OK

def f2: Int => Int = _ + 1 // OK

def g = for (i <- List(1)) yield answer // error
def g = for (i <- List(1)) yield answer // ok
}
trait Context[A]
trait Implicits {
def f[A](implicit ctx: Context[A]) = answer // error
def f[A](implicit ctx: Context[A]) = answer // ok
def g[A: Context] = answer // OK
}
class Bound[A: Context] // OK
Expand Down
48 changes: 25 additions & 23 deletions tests/neg-custom-args/fatal-warnings/i15503e.scala
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
// scalac: -Wunused:explicits

/* This goes around the "trivial method" detection */
val default_val = 1
object Foo {
/* This goes around the "trivial method" detection */
val default_val = 1

def f1(a: Int) = a // OK
def f2(a: Int) = default_val // error
def f3(a: Int)(using Int) = a // OK
def f4(a: Int)(using Int) = default_val // error
def f6(a: Int)(using Int) = summon[Int] // error
def f7(a: Int)(using Int) = summon[Int] + a // OK
private def f1(a: Int) = a // OK
private def f2(a: Int) = default_val // error
private def f3(a: Int)(using Int) = a // OK
private def f4(a: Int)(using Int) = default_val // error
private def f6(a: Int)(using Int) = summon[Int] // error
private def f7(a: Int)(using Int) = summon[Int] + a // OK
}

package scala2main.unused.args:
object happyBirthday {
def main(args: Array[String]): Unit = println("Hello World") // error
def main(args: Array[String]): Unit = println("Hello World") // ok
}

package scala2main:
Expand All @@ -29,27 +31,27 @@ package scala3main:
package foo.test.lambda.param:
val default_val = 1
val a = (i: Int) => i // OK
val b = (i: Int) => default_val // error
val b = (i: Int) => default_val // OK
val c = (_: Int) => default_val // OK

package foo.test.trivial:
/* A twisted test from Scala 2 */
class C {
def answer: 42 = 42
object X
def g0(x: Int) = ??? // OK
def f0(x: Int) = () // OK
def f1(x: Int) = throw new RuntimeException // OK
def f2(x: Int) = 42 // OK
def f3(x: Int): Option[Int] = None // OK
def f4(x: Int) = classOf[Int] // OK
def f5(x: Int) = answer + 27 // OK
def f6(x: Int) = X // OK
def f7(x: Int) = Y // OK
def f8(x: Int): List[C] = Nil // OK
def f9(x: Int): List[Int] = List(1,2,3,4) // error
def foo:Int = 32 // OK
def f77(x: Int) = foo // error
private def g0(x: Int) = ??? // OK
private def f0(x: Int) = () // OK
private def f1(x: Int) = throw new RuntimeException // OK
private def f2(x: Int) = 42 // OK
private def f3(x: Int): Option[Int] = None // OK
private def f4(x: Int) = classOf[Int] // OK
private def f5(x: Int) = answer + 27 // OK
private def f6(x: Int) = X // OK
private def f7(x: Int) = Y // OK
private def f8(x: Int): List[C] = Nil // OK
private def f9(x: Int): List[Int] = List(1,2,3,4) // error
private def foo:Int = 32 // OK
private def f77(x: Int) = foo // error
}
object Y

Expand Down
17 changes: 9 additions & 8 deletions tests/neg-custom-args/fatal-warnings/i15503f.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
/* This goes around the "trivial method" detection */
val default_int = 1

def f1(a: Int) = a // OK
def f2(a: Int) = 1 // OK
def f3(a: Int)(using Int) = a // OK
def f4(a: Int)(using Int) = default_int // OK
def f6(a: Int)(using Int) = summon[Int] // OK
def f7(a: Int)(using Int) = summon[Int] + a // OK
def f8(a: Int)(using foo: Int) = a // error

object Xd {
private def f1(a: Int) = a // OK
private def f2(a: Int) = 1 // OK
private def f3(a: Int)(using Int) = a // OK
private def f4(a: Int)(using Int) = default_int // OK
private def f6(a: Int)(using Int) = summon[Int] // OK
private def f7(a: Int)(using Int) = summon[Int] + a // OK
private def f8(a: Int)(using foo: Int) = a // error
}
23 changes: 12 additions & 11 deletions tests/neg-custom-args/fatal-warnings/i15503g.scala
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
// scalac: -Wunused:params

/* This goes around the "trivial method" detection */
val default_int = 1
object Foo {
val default_int = 1

def f1(a: Int) = a // OK
def f2(a: Int) = default_int // error
def f3(a: Int)(using Int) = a // OK
def f4(a: Int)(using Int) = default_int // error
def f6(a: Int)(using Int) = summon[Int] // error
def f7(a: Int)(using Int) = summon[Int] + a // OK

/* --- Trivial method check --- */
def g1(x: Int) = 1 // OK
def g2(x: Int) = ??? // OK
private def f1(a: Int) = a // OK
private def f2(a: Int) = default_int // error
private def f3(a: Int)(using Int) = a // OK
private def f4(a: Int)(using Int) = default_int // error
private def f6(a: Int)(using Int) = summon[Int] // error
private def f7(a: Int)(using Int) = summon[Int] + a // OK
/* --- Trivial method check --- */
private def g1(x: Int) = 1 // OK
private def g2(x: Int) = ??? // OK
}

package foo.test.i17101:
type Test[A] = A
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-custom-args/fatal-warnings/i15503h.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class A {
val b = 2 // OK

private def c = 2 // error
def d(using x:Int): Int = b // error
def d(using x:Int): Int = b // ok
def e(x: Int) = 1 // OK
def f =
val x = 1 // error
Expand Down
18 changes: 15 additions & 3 deletions tests/neg-custom-args/fatal-warnings/i15503i.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ class A {
private def c2 = 2 // OK
def c3 = c2

def d1(using x:Int): Int = default_int // error
def d1(using x:Int): Int = default_int // ok
def d2(using x:Int): Int = x // OK

def e1(x: Int) = default_int // error
def e1(x: Int) = default_int // ok
def e2(x: Int) = x // OK
def f =
val x = 1 // error
Expand All @@ -44,7 +44,8 @@ package foo.test.scala.annotation:
val default_int = 12

def a1(a: Int) = a // OK
def a2(a: Int) = default_int // error
def a2(a: Int) = default_int // ok

def a3(@unused a: Int) = default_int //OK

def b1 =
Expand Down Expand Up @@ -288,6 +289,17 @@ package foo.test.i17156:
import b.Xd
trait Z derives Xd


package foo.test.i17175:
val continue = true
def foo =
for {
i <- 1.until(10) // OK
if continue
} {
println(i)
}

package foo.test.i17117:
package example {
object test1 {
Expand Down