diff --git a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala index 7663467a3997..029830303df8 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala @@ -602,15 +602,16 @@ object CheckUnused: val dd = defn m.isDeprecated || m.is(Synthetic) - || sym.name.is(ContextFunctionParamName) // a ubiquitous parameter - || sym.name.is(ContextBoundParamName) && sym.info.typeSymbol.isMarkerTrait // a ubiquitous parameter || m.hasAnnotation(dd.UnusedAnnot) // param of unused method + || sym.name.is(ContextFunctionParamName) // a ubiquitous parameter + || sym.isCanEqual || sym.info.typeSymbol.match // more ubiquity case dd.DummyImplicitClass | dd.SubTypeClass | dd.SameTypeClass => true - case _ => false + case tps => + tps.isMarkerTrait // no members to use; was only if sym.name.is(ContextBoundParamName) + || // but consider NotGiven + tps.hasAnnotation(dd.LanguageFeatureMetaAnnot) || sym.info.isSingleton // DSL friendly - || sym.isCanEqual - || sym.info.typeSymbol.hasAnnotation(dd.LanguageFeatureMetaAnnot) || sym.info.isInstanceOf[RefinedType] // can't be expressed as a context bound if ctx.settings.WunusedHas.implicits && !infos.skip(m) diff --git a/tests/warn/i15503f.scala b/tests/warn/i15503f.scala index 94d264985c26..c2eef8a529c5 100644 --- a/tests/warn/i15503f.scala +++ b/tests/warn/i15503f.scala @@ -19,7 +19,7 @@ trait T object T: def hole(using T) = () -class C(using T) // warn +class C(using T) // no warn marker trait is evidence only class D(using T): def t = T.hole // nowarn @@ -53,7 +53,8 @@ object Unmatched: case _ => e -trait Ctx +trait Ctx: + val state: Int case class K(i: Int)(using val ctx: Ctx) // nowarn class L(val i: Int)(using val ctx: Ctx) // nowarn class M(val i: Int)(using ctx: Ctx) // warn diff --git a/tests/warn/i22969.scala b/tests/warn/i22969.scala new file mode 100644 index 000000000000..ed0f38f1aba1 --- /dev/null +++ b/tests/warn/i22969.scala @@ -0,0 +1,10 @@ +//> using options -Werror -Wunused:all +import scala.util.NotGiven + +object Test { + def f[T](a: Int)(using NotGiven[T <:< Int]) = a + 2 +} + +trait Furthermore: + type Intish[A] = A <:< Int + def f[A: Intish] = () diff --git a/tests/warn/scala2-t11681.scala b/tests/warn/scala2-t11681.scala index 507b58bf2277..adbf5ea41299 100644 --- a/tests/warn/scala2-t11681.scala +++ b/tests/warn/scala2-t11681.scala @@ -98,7 +98,7 @@ trait Anonymous { } trait Context[A] trait Implicits { - def f[A](implicit ctx: Context[A]) = answer // warn implicit param even though only marker + def f[A](implicit ctx: Context[A]) = answer // no warn after all; previously, warn implicit param even though marker def g[A: Context] = answer // no warn bound that is marker only } class Bound[A: Context] // no warn bound that is marker only