@@ -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