Skip to content

Backport "Fix WUnused for accessible symbols that are renamed" #17265

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

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
0f85c64
Fix #16822
PaulCoral Feb 15, 2023
609bc59
Traverse annotations instead of just registering
PaulCoral Feb 18, 2023
557640e
WUnused: Fix unused warnining in synthetic symbols
szymon-rd Feb 27, 2023
b009fd5
Move tests
szymon-rd Feb 28, 2023
5abf61f
Remove unused import
szymon-rd Feb 28, 2023
efa502a
WUnused: Fix for symbols with synthetic names and unused transparent …
szymon-rd Mar 7, 2023
3969ba9
Adjust assertions in test
szymon-rd Mar 8, 2023
4cdc72f
Check if import contains transparent inline in registerImport
szymon-rd Mar 10, 2023
0da834e
Warn for synthetic using/givens with wunused
szymon-rd Mar 28, 2023
87e3510
Wunused: only filter out non-zero span-length givens
szymon-rd Mar 28, 2023
e8e5656
Skip all symbols with $ in name in Wunused
szymon-rd Mar 29, 2023
fd49eb6
Add a failing case with named using to test Wunused:implicits
szymon-rd Mar 29, 2023
b3c6071
Replace for with exists in isTransparentInline in WUNused
szymon-rd Mar 29, 2023
631acaa
Register usage of symbols in non-inferred type trees in CheckUnused
KacperFKorban Feb 16, 2023
a247679
Fix WUnused with indents in derived code
szymon-rd Mar 13, 2023
27325a0
Add failsafe for a case where prefixes in CheckUnused/prepareIndent f…
szymon-rd Mar 13, 2023
f39ff92
Fix for formatting and traverse call of inlined tree in wunused
szymon-rd Mar 14, 2023
b5e69a1
Add test for wunused Inlined call
szymon-rd Mar 14, 2023
36de6da
Fix wunused false positive when deriving alias type
szymon-rd Mar 27, 2023
adede73
Fix wunused for deriving alias type that has a different name
szymon-rd Apr 3, 2023
11c7a8c
Fix test for wunused alias deriving
szymon-rd Apr 3, 2023
4acb776
Fix selecting unaliased selector in wunused
szymon-rd Apr 4, 2023
95d2fa1
Dealias only conditionally when symbol is derived val type in wunused
szymon-rd Apr 10, 2023
44bfddb
Fix WUnused for accessible symbols that are renamed
szymon-rd Mar 29, 2023
5fc9e97
Compare simple name and handle NO_NAME case in WUnused
szymon-rd Apr 12, 2023
42b6e97
Extracted isRenamedSymbol def
szymon-rd Apr 12, 2023
6bd53a8
Fix isRenamedSymbol method in WUnused
szymon-rd Apr 12, 2023
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
188 changes: 121 additions & 67 deletions compiler/src/dotty/tools/dotc/transform/CheckUnused.scala

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ trait Anonymous {
trait Context[A]
trait Implicits {
def f[A](implicit ctx: Context[A]) = answer // error
def g[A: Context] = answer // error
def g[A: Context] = answer // OK
}
class Bound[A: Context] // error
class Bound[A: Context] // OK
object Answers {
def answer: Int = 42
}
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-custom-args/fatal-warnings/i15503b.scala
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ package foo.scala2.tests:

object Types {
def l1() = {
object HiObject { def f = this } // error
object HiObject { def f = this } // OK
class Hi { // error
def f1: Hi = new Hi
def f2(x: Hi) = x
Expand Down
5 changes: 3 additions & 2 deletions tests/neg-custom-args/fatal-warnings/i15503f.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ val default_int = 1

def f1(a: Int) = a // OK
def f2(a: Int) = 1 // OK
def f3(a: Int)(using Int) = a // error
def f4(a: Int)(using Int) = default_int // error
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

4 changes: 2 additions & 2 deletions tests/neg-custom-args/fatal-warnings/i15503g.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ val default_int = 1

def f1(a: Int) = a // OK
def f2(a: Int) = default_int // error
def f3(a: Int)(using Int) = a // error
def f4(a: Int)(using Int) = default_int // error // 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

Expand Down
139 changes: 133 additions & 6 deletions tests/neg-custom-args/fatal-warnings/i15503i.scala
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ package foo.test.companionprivate:
package foo.test.i16678:
def foo(func: Int => String, value: Int): String = func(value) // OK

def run =
def run =
println(foo(number => number.toString, value = 5)) // OK
println(foo(number => "<number>", value = 5)) // error
println(foo(func = number => "<number>", value = 5)) // error
println(foo(func = number => number.toString, value = 5)) // OK
println(foo(func = _.toString, value = 5)) // OK

package foo.test.possibleclasses:
case class AllCaseClass(
k: Int, // OK
Expand All @@ -93,7 +93,7 @@ package foo.test.possibleclasses:
s: Int, // error /* But not these */
val t: Int, // OK
private val z: Int // error
)
)

case class AllCaseUsed(
k: Int, // OK
Expand All @@ -113,7 +113,7 @@ package foo.test.possibleclasses:
s: Int, // error
val t: Int, // OK
private val z: Int // error
)
)

class AllUsed(
k: Int, // OK
Expand All @@ -124,10 +124,137 @@ package foo.test.possibleclasses:
private val z: Int // OK
) {
def a = k + y + s + t + z
}
}

package foo.test.from.i16675:
case class PositiveNumber private (i: Int) // OK
object PositiveNumber:
def make(i: Int): Option[PositiveNumber] = //OK
def make(i: Int): Option[PositiveNumber] = //OK
Option.when(i >= 0)(PositiveNumber(i)) // OK

package foo.test.i16822:
enum ExampleEnum {
case Build(context: String) // OK
case List // OK
}

def demo = {
val x = ExampleEnum.List // OK
println(x) // OK
}

package foo.test.i16877:
import scala.collection.immutable.HashMap // OK
import scala.annotation.StaticAnnotation // OK

class ExampleAnnotation(val a: Object) extends StaticAnnotation // OK

@ExampleAnnotation(new HashMap()) // OK
class Test //OK

package foo.test.i16926:
def hello(): Unit =
for {
i <- (0 to 10).toList
(a, b) = "hello" -> "world" // OK
} yield println(s"$a $b")

package foo.test.i16925:
def hello =
for {
i <- 1 to 2 if true
_ = println(i) // OK
} yield ()

package foo.test.i16863a:
import scala.quoted.*
def fn(using Quotes) =
val x = Expr(1)
'{ $x + 2 } // OK

package foo.test.i16863b:
import scala.quoted.*
def fn[A](using Quotes, Type[A]) = // OK
val numeric = Expr.summon[Numeric[A]].getOrElse(???)
'{ $numeric.fromInt(3) } // OK

package foo.test.i16863c:
import scala.quoted.*
def fn[A](expr: Expr[Any])(using Quotes) =
val imp = expr match
case '{ ${ _ }: a } => Expr.summon[Numeric[a]] // OK
println(imp)

package foo.test.i16863d:
import scala.quoted.*
import scala.compiletime.asMatchable // OK
def fn[A](using Quotes, Type[A]) =
import quotes.reflect.*
val imp = TypeRepr.of[A].widen.asMatchable match
case Refinement(_,_,_) => ()
println(imp)

package foo.test.i16679a:
object myPackage:
trait CaseClassName[A]:
def name: String
object CaseClassName:
trait CaseClassByStringName[A] extends CaseClassName[A]
import scala.deriving.Mirror
object CaseClassByStringName:
inline final def derived[A](using inline A: Mirror.Of[A]): CaseClassByStringName[A] =
new CaseClassByStringName[A]:
def name: String = A.toString

object secondPackage:
import myPackage.CaseClassName // OK
case class CoolClass(i: Int) derives CaseClassName.CaseClassByStringName
println(summon[CaseClassName[CoolClass]].name)

package foo.test.i16679b:
object myPackage:
trait CaseClassName[A]:
def name: String

object CaseClassName:
import scala.deriving.Mirror
inline final def derived[A](using inline A: Mirror.Of[A]): CaseClassName[A] =
new CaseClassName[A]:
def name: String = A.toString

object Foo:
given x: myPackage.CaseClassName[secondPackage.CoolClass] = null

object secondPackage:
import myPackage.CaseClassName // OK
import Foo.x
case class CoolClass(i: Int)
println(summon[myPackage.CaseClassName[CoolClass]])

package foo.test.i17156:
package a:
trait Foo[A]
object Foo:
inline def derived[T]: Foo[T] = new Foo{}

package b:
import a.Foo
type Xd[A] = Foo[A]

package c:
import b.Xd
trait Z derives Xd

package foo.test.i17117:
package example {
object test1 {
val test = "test"
}

object test2 {

import example.test1 as t1

val test = t1.test
}
}
22 changes: 22 additions & 0 deletions tests/neg-custom-args/fatal-warnings/i16930.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// scalac: -Wunused:imports

trait Outer:
trait Used
trait Unused

object Test {
val outer: Outer = ???
import outer.{Used, Unused} // error
def foo(x: Any): Used = x.asInstanceOf[Used]
}

trait Outer1:
trait UnusedToo1
trait Unused1
def unusedToo1: UnusedToo1

object Test1 {
val outer1: Outer1 = ???
import outer1.{Unused1, UnusedToo1} // error // error
def foo() = outer1.unusedToo1 // in this case UnusedToo1 is not used explicitly, only inferred
}