From 4e3628d12bde8b425675a96f78c72483582fed24 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Sat, 30 May 2020 09:59:37 -0700 Subject: [PATCH] Promote implicit recursion to lint It was a standalone warning. Augment test example. --- .../scala/tools/nsc/settings/Warnings.scala | 5 ++++- .../scala/tools/nsc/typechecker/Implicits.scala | 2 +- test/files/neg/implicitly-self.check | 5 ++++- test/files/neg/implicitly-self.scala | 14 ++++++++++++-- test/files/pos/t11813.scala | 2 +- 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/compiler/scala/tools/nsc/settings/Warnings.scala b/src/compiler/scala/tools/nsc/settings/Warnings.scala index 59d3e87fb132..78fa456d128e 100644 --- a/src/compiler/scala/tools/nsc/settings/Warnings.scala +++ b/src/compiler/scala/tools/nsc/settings/Warnings.scala @@ -148,7 +148,8 @@ trait Warnings { val warnExtraImplicit = BooleanSetting("-Wextra-implicit", "Warn when more than one implicit parameter section is defined.") withAbbreviation "-Ywarn-extra-implicit" - val warnSelfImplicit = BooleanSetting("-Wself-implicit", "Warn when an implicit resolves to an enclosing self-definition.") withAbbreviation "-Ywarn-self-implicit" + @deprecated("Use lintImplicitRecursion", since="2.13.3") + val warnSelfImplicit = BooleanSetting("-Wself-implicit", "An implicit resolves to an enclosing definition.") withAbbreviation "-Ywarn-self-implicit" withDeprecationMessage "Use -Xlint:implicit-recursion" // Experimental lint warnings that are turned off, but which could be turned on programmatically. // They are not activated by -Xlint and can't be enabled on the command line because they are not @@ -189,6 +190,7 @@ trait Warnings { val RecurseWithDefault = LintWarning("recurse-with-default", "Recursive call used default argument.") val UnitSpecialization = LintWarning("unit-special", "Warn for specialization of Unit in parameter position.") 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.") def allLintWarnings = values.toSeq.asInstanceOf[Seq[LintWarning]] } @@ -221,6 +223,7 @@ trait Warnings { def warnRecurseWithDefault = lint contains RecurseWithDefault def unitSpecialization = lint contains UnitSpecialization def multiargInfix = lint contains MultiargInfix + def lintImplicitRecursion = lint.contains(ImplicitRecursion) || warnSelfImplicit // The Xlint warning group. val lint = MultiChoiceSetting( diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index d765567a2fd9..3c730363b775 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -125,7 +125,7 @@ trait Implicits { if (StatisticsStatics.areSomeColdStatsEnabled) statistics.stopCounter(findMemberImpl, findMemberStart) if (StatisticsStatics.areSomeColdStatsEnabled) statistics.stopCounter(subtypeImpl, subtypeStart) - if (result.isSuccess && settings.warnSelfImplicit && result.tree.symbol != null) { + if (result.isSuccess && settings.lintImplicitRecursion && result.tree.symbol != null) { val s = if (result.tree.symbol.isAccessor) result.tree.symbol.accessed else if (result.tree.symbol.isModule) result.tree.symbol.moduleClass diff --git a/test/files/neg/implicitly-self.check b/test/files/neg/implicitly-self.check index 2b7343859243..2c74eea75815 100644 --- a/test/files/neg/implicitly-self.check +++ b/test/files/neg/implicitly-self.check @@ -10,6 +10,9 @@ implicitly-self.scala:10: warning: Implicit resolves to enclosing value t implicitly-self.scala:13: warning: Implicit resolves to enclosing object tcString implicit object tcString extends TC[String] { def ix = implicitly[TC[String]].ix + 1 } ^ +implicitly-self.scala:22: warning: Implicit resolves to enclosing method bad + implicit def bad[A](a: A)(implicit ev: A => T): Sizeable = ev(a) + ^ error: No warnings can be incurred under -Werror. -4 warnings +5 warnings 1 error diff --git a/test/files/neg/implicitly-self.scala b/test/files/neg/implicitly-self.scala index c2f82af1713e..8515f1235d23 100644 --- a/test/files/neg/implicitly-self.scala +++ b/test/files/neg/implicitly-self.scala @@ -1,7 +1,7 @@ -// scalac: -Xfatal-warnings -Ywarn-self-implicit +// scalac: -Werror -Xlint:implicit-recursion // -trait TC[T] { def ix: Int } +trait TC[A] { def ix: Int } object Test { implicit def c: Char = implicitly[Char] @@ -12,3 +12,13 @@ object Test { } implicit object tcString extends TC[String] { def ix = implicitly[TC[String]].ix + 1 } } + +import language.implicitConversions + +trait T +trait Sizeable { def size: Int } + +class `t8357 warn on self-involved implicit` { + implicit def bad[A](a: A)(implicit ev: A => T): Sizeable = ev(a) + bad(new T{}) +} diff --git a/test/files/pos/t11813.scala b/test/files/pos/t11813.scala index 8ee89821c185..0e827625c690 100644 --- a/test/files/pos/t11813.scala +++ b/test/files/pos/t11813.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wself-implicit +// scalac: -Werror -Xlint:implicit-recursion // package warner