From 6d0b0c973c9878d5424629a6cad894be7c8c66c7 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Fri, 12 Dec 2025 13:47:04 -0800 Subject: [PATCH] Unused lint ignores args to ctor of enclosing class --- .../tools/dotc/transform/CheckUnused.scala | 14 ++++++++++++ tests/warn/i24698.scala | 22 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 tests/warn/i24698.scala diff --git a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala index 9ffc870e9c3d..e87f38e05f41 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala @@ -115,6 +115,13 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha if fun.symbol.is(Module) && defn.isTupleClass(fun.symbol.companionClass) then args.foreach(_.withAttachment(ForArtifact, ())) case _ => + else if !tree.tpe.isInstanceOf[MethodOrPoly] then + val f = funPart(tree) + if f.symbol.isConstructor then + f match + case Select(_: New, nme.CONSTRUCTOR) if ctx.outersIterator.exists(_.owner eq f.symbol.owner) => + ignoreArgsOfSelfConstruction(tree, f.symbol) + case _ => ctx override def transformApply(tree: Apply)(using Context): tree.type = // check for multiversal equals @@ -1011,6 +1018,13 @@ object CheckUnused: traverseChildren(tree) relaxer.traverse(tree) + def ignoreArgsOfSelfConstruction(tree: Apply, ctor: Symbol)(using Context): Unit = + val pars = ctor.denot.paramSymss.flatten.iterator.filter(_.isTerm) + val args = allTermArguments(tree) + for (par, arg) <- pars.zip(args) do + if arg.symbol.is(ParamAccessor) && arg.symbol.name == par.name && arg.symbol.owner == ctor.owner then + arg.putAttachment(Ignore, ()) + extension (nm: Name) inline def exists(p: Name => Boolean): Boolean = nm.ne(nme.NO_NAME) && p(nm) inline def isWildcard: Boolean = nm == nme.WILDCARD || nm.is(WildcardParamName) diff --git a/tests/warn/i24698.scala b/tests/warn/i24698.scala new file mode 100644 index 000000000000..d03238018652 --- /dev/null +++ b/tests/warn/i24698.scala @@ -0,0 +1,22 @@ +//> using options -Wunused:all + +trait TC[X] { + def notTrivial: Int +} + +class C[T: TC]() { // warn implicit TC used only for new instance of owner + def mod: C[T] = new C +} + +class D(val i: Int): + def this(s: String) = this(s.toInt) // not new + +class E[T](tc: TC[T]): // warn + def mod: E[T] = new E(tc) + +class F[T: TC](i: Int): // warn // warn + def mod: F[T] = new F(i) + +class G(i: Int): // warn + class Inner(i: Int): + def g = new G(i)