@@ -150,6 +150,9 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
150150 override def prepareForValDef (tree : ValDef )(using Context ): Context =
151151 if ! tree.symbol.is(Deferred ) && tree.rhs.symbol != defn.Predef_undefined then
152152 refInfos.register(tree)
153+ tree.tpt match
154+ case RefinedTypeTree (_, refinements) => relax(tree.rhs, refinements)
155+ case _ =>
153156 ctx
154157 override def transformValDef (tree : ValDef )(using Context ): tree.type =
155158 traverseAnnotations(tree.symbol)
@@ -170,11 +173,15 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
170173 override def prepareForDefDef (tree : DefDef )(using Context ): Context =
171174 def trivial = tree.symbol.is(Deferred ) || isUnconsuming(tree.rhs)
172175 def nontrivial = tree.symbol.isConstructor || tree.symbol.isAnonymousFunction
173- if ! nontrivial && trivial then refInfos.skip.addOne(tree.symbol)
176+ if ! nontrivial && trivial then
177+ refInfos.skip.addOne(tree.symbol)
174178 if tree.symbol.is(Inline ) then
175179 refInfos.inliners += 1
176180 else if ! tree.symbol.is(Deferred ) && tree.rhs.symbol != defn.Predef_undefined then
177181 refInfos.register(tree)
182+ tree.tpt match
183+ case RefinedTypeTree (_, refinements) => relax(tree.rhs, refinements)
184+ case _ =>
178185 ctx
179186 override def transformDefDef (tree : DefDef )(using Context ): tree.type =
180187 traverseAnnotations(tree.symbol)
@@ -456,7 +463,7 @@ object CheckUnused:
456463 if ! tree.name.isInstanceOf [DerivedName ] then
457464 pats.addOne((tree.symbol, tree.namePos))
458465 case tree : NamedDefTree =>
459- if (tree.symbol ne NoSymbol ) && ! tree.name.isWildcard then
466+ if (tree.symbol ne NoSymbol ) && ! tree.name.isWildcard && ! tree.hasAttachment( NoWarn ) then
460467 defs.addOne((tree.symbol, tree.namePos))
461468 case _ =>
462469 if tree.symbol ne NoSymbol then
@@ -851,6 +858,17 @@ object CheckUnused:
851858 args.foreach(traverse)
852859 case tree => traverseChildren(tree)
853860
861+ // NoWarn members in tree that correspond to refinements; currently uses only names.
862+ def relax (tree : Tree , refinements : List [Tree ])(using Context ): Unit =
863+ val names = refinements.collect { case named : NamedDefTree => named.name }.toSet
864+ val relaxer = new TreeTraverser :
865+ def traverse (tree : Tree )(using Context ) =
866+ tree match
867+ case tree : NamedDefTree if names(tree.name) => tree.withAttachment(NoWarn , ())
868+ case _ =>
869+ traverseChildren(tree)
870+ relaxer.traverse(tree)
871+
854872 extension (nm : Name )
855873 inline def exists (p : Name => Boolean ): Boolean = nm.ne(nme.NO_NAME ) && p(nm)
856874 inline def isWildcard : Boolean = nm == nme.WILDCARD || nm.is(WildcardParamName )
0 commit comments