@@ -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)
@@ -168,11 +171,15 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
168171 override def prepareForDefDef (tree : DefDef )(using Context ): Context =
169172 def trivial = tree.symbol.is(Deferred ) || isUnconsuming(tree.rhs)
170173 def nontrivial = tree.symbol.isConstructor || tree.symbol.isAnonymousFunction
171- if ! nontrivial && trivial then refInfos.skip.addOne(tree.symbol)
174+ if ! nontrivial && trivial then
175+ refInfos.skip.addOne(tree.symbol)
172176 if tree.symbol.is(Inline ) then
173177 refInfos.inliners += 1
174178 else if ! tree.symbol.is(Deferred ) && tree.rhs.symbol != defn.Predef_undefined then
175179 refInfos.register(tree)
180+ tree.tpt match
181+ case RefinedTypeTree (_, refinements) => relax(tree.rhs, refinements)
182+ case _ =>
176183 ctx
177184 override def transformDefDef (tree : DefDef )(using Context ): tree.type =
178185 traverseAnnotations(tree.symbol)
@@ -447,7 +454,7 @@ object CheckUnused:
447454 if ! tree.name.isInstanceOf [DerivedName ] then
448455 pats.addOne((tree.symbol, tree.namePos))
449456 case tree : NamedDefTree =>
450- if (tree.symbol ne NoSymbol ) && ! tree.name.isWildcard then
457+ if (tree.symbol ne NoSymbol ) && ! tree.name.isWildcard && ! tree.hasAttachment( NoWarn ) then
451458 defs.addOne((tree.symbol, tree.namePos))
452459 case _ =>
453460 if tree.symbol ne NoSymbol then
@@ -843,6 +850,17 @@ object CheckUnused:
843850 args.foreach(traverse)
844851 case tree => traverseChildren(tree)
845852
853+ // NoWarn members in tree that correspond to refinements; currently uses only names.
854+ def relax (tree : Tree , refinements : List [Tree ])(using Context ): Unit =
855+ val names = refinements.collect { case named : NamedDefTree => named.name }.toSet
856+ val relaxer = new TreeTraverser :
857+ def traverse (tree : Tree )(using Context ) =
858+ tree match
859+ case tree : NamedDefTree if names(tree.name) => tree.withAttachment(NoWarn , ())
860+ case _ =>
861+ traverseChildren(tree)
862+ relaxer.traverse(tree)
863+
846864 extension (nm : Name )
847865 inline def exists (p : Name => Boolean ): Boolean = nm.ne(nme.NO_NAME ) && p(nm)
848866 inline def isWildcard : Boolean = nm == nme.WILDCARD || nm.is(WildcardParamName )
0 commit comments