From f7b0ff6b456af3753519ae83296e43f17c3ee3f9 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Sat, 8 Mar 2025 00:08:35 -0800 Subject: [PATCH] Lazy val def member is pattern var --- compiler/src/dotty/tools/dotc/ast/Desugar.scala | 6 +++--- compiler/src/dotty/tools/dotc/transform/CheckUnused.scala | 8 ++++---- tests/warn/i15503d.scala | 6 ++++++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index d075e6a981ef..9f10e6b462e8 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -15,13 +15,11 @@ import config.Feature.{sourceVersion, migrateTo3, enabled, betterForsEnabled} import config.SourceVersion.* import collection.mutable import reporting.* -import annotation.constructorOnly import printing.Formatting.hl import config.Printers import parsing.Parsers -import scala.annotation.internal.sharable -import scala.annotation.threadUnsafe +import scala.annotation.{unchecked as _, *}, internal.sharable object desugar { import untpd.* @@ -1546,6 +1544,7 @@ object desugar { DefDef(named.name.asTermName, Nil, tpt, selector(n)) .withMods(mods &~ Lazy) .withSpan(named.span) + .withAttachment(PatternVar, ()) else valDef( ValDef(named.name.asTermName, tpt, selector(n)) @@ -1942,6 +1941,7 @@ object desugar { mayNeedSetter } + @unused private def derivedDefDef(original: Tree, named: NameTree, tpt: Tree, rhs: Tree, mods: Modifiers)(implicit src: SourceFile) = DefDef(named.name.asTermName, Nil, tpt, rhs) .withMods(mods) diff --git a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala index 4dfaea70cb50..d720010bf3d3 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala @@ -462,11 +462,11 @@ object CheckUnused: case tree: Bind => if !tree.name.isInstanceOf[DerivedName] && !tree.name.is(WildcardParamName) && !tree.hasAttachment(NoWarn) then pats.addOne((tree.symbol, tree.namePos)) - case tree: ValDef if tree.hasAttachment(PatternVar) => - if !tree.name.isInstanceOf[DerivedName] then - pats.addOne((tree.symbol, tree.namePos)) case tree: NamedDefTree => - if (tree.symbol ne NoSymbol) + if tree.hasAttachment(PatternVar) then + if !tree.name.isInstanceOf[DerivedName] then + pats.addOne((tree.symbol, tree.namePos)) + else if (tree.symbol ne NoSymbol) && !tree.name.isWildcard && !tree.hasAttachment(NoWarn) && !tree.symbol.is(ModuleVal) // track only the ModuleClass using the object symbol, with correct namePos diff --git a/tests/warn/i15503d.scala b/tests/warn/i15503d.scala index 2981986daff6..1e1adca51b46 100644 --- a/tests/warn/i15503d.scala +++ b/tests/warn/i15503d.scala @@ -115,3 +115,9 @@ object `mutable patvar in for`: class `unset var requires -Wunused`: private var i = 0 // no warn as we didn't ask for it def f = println(i) + +class `i22743 lazy vals are defs`: + def f: (Int, String) = (42, "hello, world") + lazy val (i, s) = f // no warn because def is neither local nor private + val (j, t) = f // existing no warn for val with attachment + private lazy val (k, u) = f // warn // warn a warning so nice, they warn it twice