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

Make -Wunused:imports work again even when -Ymacro-annotations is enabled #8962

Merged
merged 1 commit into from May 6, 2020
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -35,7 +35,7 @@ trait MacroAnnotationNamers { self: Analyzer =>
case tree @ Import(_, _) =>
createAssignAndEnterSymbol(tree)
finishSymbol(tree)
returnContext = context.make(tree)
returnContext = context.makeImportContext(tree)
case tree: MemberDef =>
createAssignAndEnterSymbol(tree)
finishSymbol(tree)
Expand Down
55 changes: 55 additions & 0 deletions test/files/neg/warn-unused-imports-b.check
@@ -0,0 +1,55 @@
warn-unused-imports_2.scala:135: error: type mismatch;
found : Int(42)
required: Sample.X
f(42) // error
^
warn-unused-imports_2.scala:59: warning: Unused import
import p1.A // warn
^
warn-unused-imports_2.scala:64: warning: Unused import
import p1.{ A, B } // warn on A
^
warn-unused-imports_2.scala:69: warning: Unused import
import p1.{ A, B } // warn on both
^
warn-unused-imports_2.scala:69: warning: Unused import
import p1.{ A, B } // warn on both
^
warn-unused-imports_2.scala:75: warning: Unused import
import c._ // warn
^
warn-unused-imports_2.scala:80: warning: Unused import
import p1._ // warn
^
warn-unused-imports_2.scala:87: warning: Unused import
import c._ // warn
^
warn-unused-imports_2.scala:93: warning: Unused import
import p1.c._ // warn
^
warn-unused-imports_2.scala:100: warning: Unused import
import p1._ // warn
^
warn-unused-imports_2.scala:120: warning: Unused import
import p1.A // warn
^
warn-unused-imports_2.scala:134: warning: Unused import
import Sample.Implicits._ // warn
^
warn-unused-imports_2.scala:145: warning: Unused import
import Sample.Implicits.useless // warn
^
warn-unused-imports_2.scala:149: warning: Unused import
import java.io.File // warn
^
warn-unused-imports_2.scala:150: warning: Unused import
import scala.concurrent.Future // warn
^
warn-unused-imports_2.scala:151: warning: Unused import
import scala.concurrent.ExecutionContext.Implicits.global // warn
^
warn-unused-imports_2.scala:152: warning: Unused import
import p1.A // warn
^
16 warnings
1 error
32 changes: 32 additions & 0 deletions test/files/neg/warn-unused-imports-b/sample_1.scala
@@ -0,0 +1,32 @@

import language._

object Sample {
trait X
trait Y

// import of the non-implicit should be unused
object Implicits {
def `int to X`(i: Int): X = null
implicit def `int to Y`(i: Int): Y = null
implicit def useless(i: Int): String = null
}

def f(x: X) = ???
def g(y: Y) = ???
}

import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context

object Macro {
def f: Int = macro fImpl
def fImpl(c: Context): c.Tree = {
import c.universe._

q"""
import scala.util.Random
42 // TODO randomize
"""
}
}
161 changes: 161 additions & 0 deletions test/files/neg/warn-unused-imports-b/warn-unused-imports_2.scala
@@ -0,0 +1,161 @@
// scalac: -Werror -Wunused:imports -Ymacro-annotations
//
class Bippo {
def length: Int = 123
class Tree
}

package object p1 {
class A
implicit class B(val s: String) { def bippy = s }
val c: Bippo = new Bippo
type D = String
}
package object p2 {
class A
implicit class B(val s: String) { def bippy = s }
val c: Bippo = new Bippo
type D = Int
}

trait NoWarn {
{
import p1._ // no warn
println("abc".bippy)
}

{
import p1._ // no warn
println(new A)
}

{
import p1.B // no warn
println("abc".bippy)
}

{
import p1._ // no warn
import c._ // no warn
println(length)
}

{
import p1._ // no warn
import c._ // no warn
val x: Tree = null
println(x)
}

{
import p1.D // no warn
val x: D = null
println(x)
}
}

trait Warn {
{
import p1.A // warn
println(123)
}

{
import p1.{ A, B } // warn on A
println("abc".bippy)
}

{
import p1.{ A, B } // warn on both
println(123)
}

{
import p1._ // no warn (technically this could warn, but not worth the effort to unroll unusedness transitively)
import c._ // warn
println(123)
}

{
import p1._ // warn
println(123)
}

{
class Tree
import p1._ // no warn
import c._ // warn
val x: Tree = null
println(x)
}

{
import p1.c._ // warn
println(123)
}
}

trait Nested {
{
import p1._ // warn
trait Warn { // don't warn about unused local trait with -Ywarn-unused:imports
import p2._
println(new A)
println("abc".bippy)
}
println("")
}

{
import p1._ // no warn
trait NoWarn {
import p2.B // no warn
println("abc".bippy)
println(new A)
}
println(new NoWarn { })
}

{
import p1.A // warn
trait Warn {
import p2.A
println(new A)
}
println(new Warn { })
}
}

// test unusage of imports from other compilation units after implicit search
trait Outsiders {
{
//implicit search should not disable warning
import Sample._
import Sample.Implicits._ // warn
f(42) // error
}
{
import Sample._
import Sample.Implicits._ // nowarn
g(42) // ok
}
{
import Sample._
import Sample.Implicits.`int to Y` // nowarn
import Sample.Implicits.useless // warn
g(42) // ok
}
{
import java.io.File // warn
import scala.concurrent.Future // warn
import scala.concurrent.ExecutionContext.Implicits.global // warn
import p1.A // warn
import p1.B // no warn
println("abc".bippy)
//Future("abc".bippy)
}
}

class MacroClient {
def x = Macro.f // don't crash; but also don't warn on expansion, see scala/bug#10270 and [pos|neg]/t10270
}
@@ -1,4 +1,4 @@
// scalac: -Xfatal-warnings -Ywarn-unused:imports
// scalac: -Werror -Wunused:imports
//
class Bippo {
def length: Int = 123
Expand Down