@@ -61,7 +61,6 @@ class CheckUnused extends MiniPhase:
6161 // ========== SETUP ============
6262
6363 override def prepareForUnit (tree : tpd.Tree )(using Context ): Context =
64- val tree = ctx.compilationUnit.tpdTree
6564 val data = UnusedData ()
6665 val fresh = ctx.fresh.setProperty(_key, data)
6766 fresh
@@ -94,7 +93,11 @@ class CheckUnused extends MiniPhase:
9493 pushInBlockTemplatePackageDef(tree)
9594
9695 override def prepareForValDef (tree : tpd.ValDef )(using Context ): Context =
97- _key.unusedDataApply(_.registerDef(tree))
96+ _key.unusedDataApply{ud =>
97+ ud.registerDef(tree)
98+ if tree.symbol.is(Flags .Module ) then
99+ ud.addIgnoredUsage(tree.symbol)
100+ }
98101
99102 override def prepareForDefDef (tree : tpd.DefDef )(using Context ): Context =
100103 _key.unusedDataApply{ ud =>
@@ -103,6 +106,12 @@ class CheckUnused extends MiniPhase:
103106 ud.registerDef(tree)
104107 }
105108
109+ override def prepareForTypeDef (tree : tpd.TypeDef )(using Context ): Context =
110+ _key.unusedDataApply{ ud =>
111+ ud.registerDef(tree)
112+ ud.addIgnoredUsage(tree.symbol)
113+ }
114+
106115 override def prepareForBind (tree : tpd.Bind )(using Context ): Context =
107116 _key.unusedDataApply(_.registerPatVar(tree))
108117
@@ -112,6 +121,11 @@ class CheckUnused extends MiniPhase:
112121
113122 // ========== MiniPhase Transform ==========
114123
124+ override def transformValDef (tree : tpd.ValDef )(using Context ): tpd.Tree =
125+ if tree.symbol.is(Flags .Module ) then
126+ _key.unusedDataApply(_.removeIgnoredUsage(tree.symbol))
127+ tree
128+
115129 override def transformBlock (tree : tpd.Block )(using Context ): tpd.Tree =
116130 popOutBlockTemplatePackageDef()
117131 tree
@@ -124,6 +138,10 @@ class CheckUnused extends MiniPhase:
124138 popOutBlockTemplatePackageDef()
125139 tree
126140
141+ override def transformTypeDef (tree : tpd.TypeDef )(using Context ): tpd.Tree =
142+ _key.unusedDataApply(_.removeIgnoredUsage(tree.symbol))
143+ tree
144+
127145 // ---------- MiniPhase HELPERS -----------
128146
129147 private def pushInBlockTemplatePackageDef (tree : tpd.Block | tpd.Template | tpd.PackageDef )(using Context ): Context =
@@ -175,6 +193,9 @@ class CheckUnused extends MiniPhase:
175193 case t: tpd.DefDef =>
176194 prepareForDefDef(t)
177195 traverseChildren(tree)(using newCtx)
196+ case t: tpd.TypeDef =>
197+ prepareForTypeDef(t)
198+ traverseChildren(tree)(using newCtx)
178199 case t : tpd.Bind =>
179200 prepareForBind(t)
180201 traverseChildren(tree)(using newCtx)
@@ -255,21 +276,23 @@ object CheckUnused:
255276 private val unusedImport = MutSet [ImportSelector ]()
256277
257278 /* LOCAL DEF OR VAL / Private Def or Val / Pattern variables */
258- private val localDefInScope = MutSet [tpd.ValOrDefDef ]()
259- private val privateDefInScope = MutSet [tpd.ValOrDefDef ]()
260- private val explicitParamInScope = MutSet [tpd.ValOrDefDef ]()
261- private val implicitParamInScope = MutSet [tpd.ValOrDefDef ]()
279+ private val localDefInScope = MutSet [tpd.MemberDef ]()
280+ private val privateDefInScope = MutSet [tpd.MemberDef ]()
281+ private val explicitParamInScope = MutSet [tpd.MemberDef ]()
282+ private val implicitParamInScope = MutSet [tpd.MemberDef ]()
262283 private val patVarsInScope = MutSet [tpd.Bind ]()
263284
264285 /* Unused collection collected at the end */
265- private val unusedLocalDef = MutSet [tpd.ValOrDefDef ]()
266- private val unusedPrivateDef = MutSet [tpd.ValOrDefDef ]()
267- private val unusedExplicitParams = MutSet [tpd.ValOrDefDef ]()
268- private val unusedImplicitParams = MutSet [tpd.ValOrDefDef ]()
286+ private val unusedLocalDef = MutSet [tpd.MemberDef ]()
287+ private val unusedPrivateDef = MutSet [tpd.MemberDef ]()
288+ private val unusedExplicitParams = MutSet [tpd.MemberDef ]()
289+ private val unusedImplicitParams = MutSet [tpd.MemberDef ]()
269290 private val unusedPatVars = MutSet [tpd.Bind ]()
270291
271292 /** All used symbols */
272293 private val usedDef = MutSet [Symbol ]()
294+ /** Do not register as used */
295+ private val doNotRegister = MutSet [Symbol ]()
273296
274297 /** Trivial definitions, avoid registering params */
275298 private val trivialDefs = MutSet [Symbol ]()
@@ -296,14 +319,30 @@ object CheckUnused:
296319 * as the same element can be imported with different renaming
297320 */
298321 def registerUsed (sym : Symbol , name : Option [Name ])(using Context ): Unit =
299- if ! isConstructorOfSynth(sym) then
322+ if ! isConstructorOfSynth(sym) && ! doNotRegister(sym) then
300323 usedInScope.top += ((sym, sym.isAccessibleAsIdent, name))
301324 if sym.isConstructor && sym.exists then
302325 registerUsed(sym.owner, None ) // constructor are "implicitly" imported with the class
303326
304327 /** Register a list of found (used) symbols */
305328 def registerUsed (syms : Seq [Symbol ])(using Context ): Unit =
306- usedInScope.top ++= syms.filterNot(isConstructorOfSynth).map(s => (s, s.isAccessibleAsIdent, None ))
329+ usedInScope.top ++=
330+ syms
331+ .filterNot(s => isConstructorOfSynth(s) || doNotRegister(s))
332+ .map(s => (s, s.isAccessibleAsIdent, None ))
333+
334+ /** Register a symbol that should be ignored */
335+ def addIgnoredUsage (sym : Symbol )(using Context ): Unit =
336+ doNotRegister += sym
337+ if sym.is(Flags .Module ) then
338+ doNotRegister += sym.moduleClass
339+
340+ /** Remove a symbol that shouldn't be ignored anymore */
341+ def removeIgnoredUsage (sym : Symbol )(using Context ): Unit =
342+ doNotRegister -= sym
343+ if sym.is(Flags .Module ) then
344+ doNotRegister -= sym.moduleClass
345+
307346
308347 /** Register an import */
309348 def registerImport (imp : tpd.Import )(using Context ): Unit =
@@ -314,19 +353,19 @@ object CheckUnused:
314353 }
315354
316355 /** Register (or not) some `val` or `def` according to the context, scope and flags */
317- def registerDef (valOrDef : tpd.ValOrDefDef )(using Context ): Unit =
356+ def registerDef (memDef : tpd.MemberDef )(using Context ): Unit =
318357 // register the annotations for usage
319- registerUsedAnnotation(valOrDef .symbol)
320- if ! valOrDef .symbol.isUnusedAnnot then
321- if valOrDef .symbol.is(Param ) && ! isSyntheticMainParam(valOrDef .symbol) && ! valOrDef .symbol.ownerIsTrivial then
322- if valOrDef .symbol.isOneOf(GivenOrImplicit ) then
323- implicitParamInScope += valOrDef
358+ registerUsedAnnotation(memDef .symbol)
359+ if ! memDef .symbol.isUnusedAnnot then
360+ if memDef .symbol.is(Param ) && ! isSyntheticMainParam(memDef .symbol) && ! memDef .symbol.ownerIsTrivial then
361+ if memDef .symbol.isOneOf(GivenOrImplicit ) then
362+ implicitParamInScope += memDef
324363 else
325- explicitParamInScope += valOrDef
364+ explicitParamInScope += memDef
326365 else if currScopeType.top == ScopeType .Local then
327- localDefInScope += valOrDef
328- else if currScopeType.top == ScopeType .Template && valOrDef .symbol.is(Private , butNot = SelfName ) then
329- privateDefInScope += valOrDef
366+ localDefInScope += memDef
367+ else if currScopeType.top == ScopeType .Template && memDef .symbol.is(Private , butNot = SelfName ) then
368+ privateDefInScope += memDef
330369
331370 /** Register pattern variable */
332371 def registerPatVar (patvar : tpd.Bind )(using Context ): Unit =
0 commit comments