Skip to content

Collect nowarn symbols instead of skipping them #22766

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions compiler/src/dotty/tools/dotc/transform/CheckUnused.scala
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ object CheckUnused:
val refs = mutable.Set.empty[Symbol] // references
val asss = mutable.Set.empty[Symbol] // targets of assignment
val skip = mutable.Set.empty[Symbol] // methods to skip (don't warn about their params)
val nowarn = mutable.Set.empty[Symbol] // marked @nowarn
val imps = new IdentityHashMap[Import, Unit] // imports
val sels = new IdentityHashMap[ImportSelector, Unit] // matched selectors
def register(tree: Tree)(using Context): Unit = if inlined.isEmpty then
Expand All @@ -462,17 +463,20 @@ object CheckUnused:
then
imps.put(imp, ())
case tree: Bind =>
if !tree.name.isInstanceOf[DerivedName] && !tree.name.is(WildcardParamName) && !tree.hasAttachment(NoWarn) then
if !tree.name.isInstanceOf[DerivedName] && !tree.name.is(WildcardParamName) then
if tree.hasAttachment(NoWarn) then
nowarn.addOne(tree.symbol)
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)
&& !tree.name.isWildcard
&& !tree.hasAttachment(NoWarn)
&& !tree.symbol.is(ModuleVal) // track only the ModuleClass using the object symbol, with correct namePos
then
if tree.hasAttachment(NoWarn) then
nowarn.addOne(tree.symbol)
defs.addOne((tree.symbol.userSymbol, tree.namePos))
case _ =>
if tree.symbol ne NoSymbol then
Expand Down Expand Up @@ -540,6 +544,7 @@ object CheckUnused:
&& !sym.name.is(BodyRetainerName)
&& !sym.isSerializationSupport
&& !(sym.is(Mutable) && sym.isSetter && sym.owner.is(Trait)) // tracks sym.underlyingSymbol sibling getter
&& !infos.nowarn(sym)
then
warnAt(pos)(UnusedSymbol.privateMembers)

Expand Down Expand Up @@ -634,7 +639,7 @@ object CheckUnused:
val byPos = infos.pats.groupMap(uniformPos(_, _))((sym, pos) => sym)
for (pos, syms) <- byPos if pos.span.exists && !syms.exists(_.hasAnnotation(defn.UnusedAnnot)) do
if !syms.exists(infos.refs(_)) then
if !syms.exists(v => !v.isLocal && !v.is(Private)) then
if !syms.exists(v => !v.isLocal && !v.is(Private) || infos.nowarn(v)) then
warnAt(pos)(UnusedSymbol.patVars)
else if syms.exists(_.is(Mutable)) then // check unassigned var
val sym = // recover the original
Expand Down
2 changes: 1 addition & 1 deletion tests/warn/i15503d.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ case class K(i: Int, j: Int)

class C(c0: Option[Int], k0: K):
private val Some(c) = c0: @unchecked // warn valdef from pattern
private val K(i, j) = k0 // warn // warn valdefs from pattern (RHS patvars are NoWarn)
private val K(i, j) = k0 // nowarn (name of case class element is nowarn)
val K(v, w) = k0 // nowarn nonprivate
private val K(r, s) = k0 // warn // warn valdefs from pattern
def f(x: Option[Int]) = x match
Expand Down
10 changes: 10 additions & 0 deletions tests/warn/t13095.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//> using options -Wunused:patvars -Werror

case class A(x: Int, y: Int)

object Main {
for {
a <- List.empty[A]
A(x, y) = a
} yield x + y
}
Loading