From d848ec9192080fbb92d085e8c1334ef8db0ca07a Mon Sep 17 00:00:00 2001 From: som-snytt Date: Mon, 14 Jul 2025 14:50:50 -0700 Subject: [PATCH 1/2] Use result of lambda type of implicit in CheckUnused (#23497) Fixes #23494 When inspecting unused implicit parameters, the check skips parameters which are "marker traits". It tests for any members of the type (or its upper bound) which are not "universal members". This commit uses the `resultType` to avoid an error ``` invalid new prefix ``` while computing members where the type is a `LambdaType`. A future improvement would be not to request `allMembers`, since the check only needs to find one that is not universal. The necessitating change was https://github.com/scala/scala3/commit/2e4bc0abb8a374d78fe1aac383f3208b5efb5eb1. --- .../dotty/tools/dotc/transform/CheckUnused.scala | 2 +- tests/warn/i15503f.scala | 7 ++++++- tests/warn/i23494.scala | 15 +++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 tests/warn/i23494.scala diff --git a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala index e22b2442de48..43774a209ebb 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala @@ -964,7 +964,7 @@ object CheckUnused: def isCanEqual: Boolean = sym.isOneOf(GivenOrImplicit) && sym.info.finalResultType.baseClasses.exists(_.derivesFrom(defn.CanEqualClass)) def isMarkerTrait: Boolean = - sym.info.hiBound.allMembers.forall: d => + sym.info.hiBound.resultType.allMembers.forall: d => val m = d.symbol !m.isTerm || m.isSelfSym || m.is(Method) && (m.owner == defn.AnyClass || m.owner == defn.ObjectClass) def isEffectivelyPrivate: Boolean = diff --git a/tests/warn/i15503f.scala b/tests/warn/i15503f.scala index 7c3483411f86..684bee3313e8 100644 --- a/tests/warn/i15503f.scala +++ b/tests/warn/i15503f.scala @@ -1,4 +1,4 @@ -//> using options -Wunused:implicits +//> using options -Wunused:implicits /* This goes around the "trivial method" detection */ val default_int = 1 @@ -58,6 +58,8 @@ package givens: trait Y: def doY: String + trait Z + given X with def doX = 7 @@ -75,6 +77,9 @@ package givens: given namely (using x: X): Y with // warn protected param to given class def doY = "8" + + def f(using => X) = println() // warn + def g(using => Z) = println() // nowarn marker trait end givens object i22895: diff --git a/tests/warn/i23494.scala b/tests/warn/i23494.scala new file mode 100644 index 000000000000..c3c0c5a2e0bc --- /dev/null +++ b/tests/warn/i23494.scala @@ -0,0 +1,15 @@ +//> using options -Wunused:implicits + +import scala.deriving.Mirror + +abstract class EnumerationValues[A]: + type Out + +object EnumerationValues: + type Aux[A, B] = EnumerationValues[A] { type Out = B } + + def apply[A, B](): EnumerationValues.Aux[A, B] = new EnumerationValues[A]: + override type Out = B + + given sum[A, B <: Tuple](using mirror: Mirror.SumOf[A] { type MirroredElemTypes = B }): EnumerationValues.Aux[A, A] = + EnumerationValues[A, A]() From 0214f81d47ca3c440763e5ea6598524320751a2e Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Wed, 23 Jul 2025 15:10:02 +0200 Subject: [PATCH 2/2] Use result of lambda type of implicit in CheckUnused (#23497) Fixes #23494 When inspecting unused implicit parameters, the check skips parameters which are "marker traits". It tests for any members of the type (or its upper bound) which are not "universal members". This commit uses the `resultType` to avoid an error ``` invalid new prefix ``` while computing members where the type is a `LambdaType`. A future improvement would be not to request `allMembers`, since the check only needs to find one that is not universal. The necessitating change was https://github.com/scala/scala3/commit/2e4bc0abb8a374d78fe1aac383f3208b5efb5eb1. [Cherry-picked a5e15ab7d7b271272c9e1ac1d2837425ec592214][modified]