From 9b505e2cf1aead57b5354ce72be8743a923498e7 Mon Sep 17 00:00:00 2001 From: Chris Birchall Date: Thu, 12 Mar 2020 15:03:03 +0000 Subject: [PATCH] Support macro annotation expansions in -Wmacros:MODE Specifically, for `-Wmacros:none` or `-Wmacros:before`, we shouldn't warn about unused symbols in code resulting from expansion of a macro annotation. --- .../nsc/typechecker/TypeDiagnostics.scala | 6 +++-- test/files/neg/macro-annot-unused-param.check | 6 +++++ .../macro-annot-unused-param/Macros_1.scala | 22 +++++++++++++++++++ .../neg/macro-annot-unused-param/Test_2.scala | 7 ++++++ .../macro-annot-unused-param/Macros_1.scala | 22 +++++++++++++++++++ .../pos/macro-annot-unused-param/Test_2.scala | 7 ++++++ 6 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 test/files/neg/macro-annot-unused-param.check create mode 100644 test/files/neg/macro-annot-unused-param/Macros_1.scala create mode 100644 test/files/neg/macro-annot-unused-param/Test_2.scala create mode 100644 test/files/pos/macro-annot-unused-param/Macros_1.scala create mode 100644 test/files/pos/macro-annot-unused-param/Test_2.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index 91ecf0e5103f..cfb546b503cd 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -651,11 +651,13 @@ trait TypeDiagnostics { } object skipMacroExpansion extends UnusedPrivates { override def traverse(t: Tree): Unit = - if (!hasMacroExpansionAttachment(t)) super.traverse(t) + if (!hasMacroExpansionAttachment(t) && !(t.hasSymbol && isExpanded(t.symbol))) + super.traverse(t) } object checkMacroExpandee extends UnusedPrivates { override def traverse(t: Tree): Unit = - super.traverse(if (hasMacroExpansionAttachment(t)) macroExpandee(t) else t) + if (!(t.hasSymbol && isExpanded(t.symbol))) + super.traverse(if (hasMacroExpansionAttachment(t)) macroExpandee(t) else t) } private def warningsEnabled: Boolean = { diff --git a/test/files/neg/macro-annot-unused-param.check b/test/files/neg/macro-annot-unused-param.check new file mode 100644 index 000000000000..f23c11962c34 --- /dev/null +++ b/test/files/neg/macro-annot-unused-param.check @@ -0,0 +1,6 @@ +Test_2.scala:2: warning: parameter value x in anonymous function is never used +@mymacro + ^ +error: No warnings can be incurred under -Werror. +1 warning +1 error diff --git a/test/files/neg/macro-annot-unused-param/Macros_1.scala b/test/files/neg/macro-annot-unused-param/Macros_1.scala new file mode 100644 index 000000000000..17d602216c23 --- /dev/null +++ b/test/files/neg/macro-annot-unused-param/Macros_1.scala @@ -0,0 +1,22 @@ +// scalac: -Ymacro-annotations +import scala.language.experimental.macros +import scala.reflect.macros.blackbox.Context +import scala.annotation.StaticAnnotation + +object Macros { + def annotImpl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { + import c.universe._ + val classTree = annottees.head.tree + val objectTree = q""" + object X { + def f: Int => String = { x => "hello" } + } + """ + + c.Expr[Any](Block(List(classTree, objectTree), Literal(Constant(())))) + } +} + +class mymacro extends StaticAnnotation { + def macroTransform(annottees: Any*): Any = macro Macros.annotImpl +} diff --git a/test/files/neg/macro-annot-unused-param/Test_2.scala b/test/files/neg/macro-annot-unused-param/Test_2.scala new file mode 100644 index 000000000000..6ac2d3f50eeb --- /dev/null +++ b/test/files/neg/macro-annot-unused-param/Test_2.scala @@ -0,0 +1,7 @@ +// scalac: -Ymacro-annotations -Wunused:params -Wmacros:after -Werror +@mymacro +class X + +object Test { + println(X.f(123)) +} diff --git a/test/files/pos/macro-annot-unused-param/Macros_1.scala b/test/files/pos/macro-annot-unused-param/Macros_1.scala new file mode 100644 index 000000000000..17d602216c23 --- /dev/null +++ b/test/files/pos/macro-annot-unused-param/Macros_1.scala @@ -0,0 +1,22 @@ +// scalac: -Ymacro-annotations +import scala.language.experimental.macros +import scala.reflect.macros.blackbox.Context +import scala.annotation.StaticAnnotation + +object Macros { + def annotImpl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { + import c.universe._ + val classTree = annottees.head.tree + val objectTree = q""" + object X { + def f: Int => String = { x => "hello" } + } + """ + + c.Expr[Any](Block(List(classTree, objectTree), Literal(Constant(())))) + } +} + +class mymacro extends StaticAnnotation { + def macroTransform(annottees: Any*): Any = macro Macros.annotImpl +} diff --git a/test/files/pos/macro-annot-unused-param/Test_2.scala b/test/files/pos/macro-annot-unused-param/Test_2.scala new file mode 100644 index 000000000000..9f101f7491da --- /dev/null +++ b/test/files/pos/macro-annot-unused-param/Test_2.scala @@ -0,0 +1,7 @@ +// scalac: -Ymacro-annotations -Wunused:params -Werror +@mymacro +class X + +object Test { + println(X.f(123)) +}