Skip to content

Commit 4750edc

Browse files
committed
Merge branch 'main' into fix/wunused/annotations
2 parents 4cc4339 + b5b24d9 commit 4750edc

File tree

2 files changed

+53
-26
lines changed

2 files changed

+53
-26
lines changed

compiler/src/dotty/tools/dotc/transform/CheckUnused.scala

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,11 @@ class CheckUnused extends MiniPhase:
4747
*/
4848
private val _key = Property.Key[UnusedData]
4949

50-
extension (k: Property.Key[UnusedData])
51-
private def unusedDataApply[U](f: UnusedData => U)(using Context): Context =
52-
ctx.property(_key).foreach(f)
53-
ctx
54-
private def getUnusedData(using Context): Option[UnusedData] =
55-
ctx.property(_key)
50+
private def unusedDataApply[U](f: UnusedData => U)(using Context): Context =
51+
ctx.property(_key).foreach(f)
52+
ctx
53+
private def getUnusedData(using Context): Option[UnusedData] =
54+
ctx.property(_key)
5655

5756
override def phaseName: String = CheckUnused.phaseName
5857

@@ -72,7 +71,7 @@ class CheckUnused extends MiniPhase:
7271
// ========== END + REPORTING ==========
7372

7473
override def transformUnit(tree: tpd.Tree)(using Context): tpd.Tree =
75-
_key.unusedDataApply(ud => reportUnused(ud.getUnused))
74+
unusedDataApply(ud => reportUnused(ud.getUnused))
7675
tree
7776

7877
// ========== MiniPhase Prepare ==========
@@ -83,14 +82,14 @@ class CheckUnused extends MiniPhase:
8382

8483
override def prepareForIdent(tree: tpd.Ident)(using Context): Context =
8584
if tree.symbol.exists then
86-
_key.unusedDataApply(_.registerUsed(tree.symbol, Some(tree.name)))
85+
unusedDataApply(_.registerUsed(tree.symbol, Some(tree.name)))
8786
else if tree.hasType then
88-
_key.unusedDataApply(_.registerUsed(tree.tpe.classSymbol, Some(tree.name)))
87+
unusedDataApply(_.registerUsed(tree.tpe.classSymbol, Some(tree.name)))
8988
else
9089
ctx
9190

9291
override def prepareForSelect(tree: tpd.Select)(using Context): Context =
93-
_key.unusedDataApply(_.registerUsed(tree.symbol, Some(tree.name)))
92+
unusedDataApply(_.registerUsed(tree.symbol, Some(tree.name)))
9493

9594
override def prepareForBlock(tree: tpd.Block)(using Context): Context =
9695
pushInBlockTemplatePackageDef(tree)
@@ -102,7 +101,7 @@ class CheckUnused extends MiniPhase:
102101
pushInBlockTemplatePackageDef(tree)
103102

104103
override def prepareForValDef(tree: tpd.ValDef)(using Context): Context =
105-
_key.unusedDataApply{ud =>
104+
unusedDataApply{ud =>
106105
// do not register the ValDef generated for `object`
107106
traverseAnnotations(tree.symbol)
108107
if !tree.symbol.is(Module) then
@@ -111,7 +110,7 @@ class CheckUnused extends MiniPhase:
111110
}
112111

113112
override def prepareForDefDef(tree: tpd.DefDef)(using Context): Context =
114-
_key.unusedDataApply{ ud =>
113+
unusedDataApply{ ud =>
115114
import ud.registerTrivial
116115
tree.registerTrivial
117116
traverseAnnotations(tree.symbol)
@@ -120,7 +119,7 @@ class CheckUnused extends MiniPhase:
120119
}
121120

122121
override def prepareForTypeDef(tree: tpd.TypeDef)(using Context): Context =
123-
_key.unusedDataApply{ ud =>
122+
unusedDataApply{ ud =>
124123
if !tree.symbol.is(Param) then // Ignore type parameter (as Scala 2)
125124
traverseAnnotations(tree.symbol)
126125
ud.registerDef(tree)
@@ -129,10 +128,10 @@ class CheckUnused extends MiniPhase:
129128

130129
override def prepareForBind(tree: tpd.Bind)(using Context): Context =
131130
traverseAnnotations(tree.symbol)
132-
_key.unusedDataApply(_.registerPatVar(tree))
131+
unusedDataApply(_.registerPatVar(tree))
133132

134133
override def prepareForTypeTree(tree: tpd.TypeTree)(using Context): Context =
135-
typeTraverser(_key.unusedDataApply).traverse(tree.tpe)
134+
if !tree.isInstanceOf[tpd.InferredTypeTree] then typeTraverser(unusedDataApply).traverse(tree.tpe)
136135
ctx
137136

138137
// ========== MiniPhase Transform ==========
@@ -150,27 +149,27 @@ class CheckUnused extends MiniPhase:
150149
tree
151150

152151
override def transformValDef(tree: tpd.ValDef)(using Context): tpd.Tree =
153-
_key.unusedDataApply(_.removeIgnoredUsage(tree.symbol))
152+
unusedDataApply(_.removeIgnoredUsage(tree.symbol))
154153
tree
155154

156155
override def transformDefDef(tree: tpd.DefDef)(using Context): tpd.Tree =
157-
_key.unusedDataApply(_.removeIgnoredUsage(tree.symbol))
156+
unusedDataApply(_.removeIgnoredUsage(tree.symbol))
158157
tree
159158

160159
override def transformTypeDef(tree: tpd.TypeDef)(using Context): tpd.Tree =
161-
_key.unusedDataApply(_.removeIgnoredUsage(tree.symbol))
160+
unusedDataApply(_.removeIgnoredUsage(tree.symbol))
162161
tree
163162

164163
// ---------- MiniPhase HELPERS -----------
165164

166165
private def pushInBlockTemplatePackageDef(tree: tpd.Block | tpd.Template | tpd.PackageDef)(using Context): Context =
167-
_key.unusedDataApply { ud =>
166+
unusedDataApply { ud =>
168167
ud.pushScope(UnusedData.ScopeType.fromTree(tree))
169168
}
170169
ctx
171170

172171
private def popOutBlockTemplatePackageDef()(using Context): Context =
173-
_key.unusedDataApply { ud =>
172+
unusedDataApply { ud =>
174173
ud.popScope()
175174
}
176175
ctx
@@ -193,7 +192,7 @@ class CheckUnused extends MiniPhase:
193192
val newCtx = if tree.symbol.exists then ctx.withOwner(tree.symbol) else ctx
194193
tree match
195194
case imp:tpd.Import =>
196-
_key.unusedDataApply(_.registerImport(imp))
195+
unusedDataApply(_.registerImport(imp))
197196
traverseChildren(tree)(using newCtx)
198197
case ident: Ident =>
199198
prepareForIdent(ident)
@@ -203,7 +202,7 @@ class CheckUnused extends MiniPhase:
203202
traverseChildren(tree)(using newCtx)
204203
case _: (tpd.Block | tpd.Template | tpd.PackageDef) =>
205204
//! DIFFERS FROM MINIPHASE
206-
_key.unusedDataApply { ud =>
205+
unusedDataApply { ud =>
207206
ud.inNewScope(ScopeType.fromTree(tree))(traverseChildren(tree)(using newCtx))
208207
}
209208
case t:tpd.ValDef =>
@@ -221,9 +220,10 @@ class CheckUnused extends MiniPhase:
221220
case t: tpd.Bind =>
222221
prepareForBind(t)
223222
traverseChildren(tree)(using newCtx)
223+
case _: tpd.InferredTypeTree =>
224224
case t@tpd.TypeTree() =>
225225
//! DIFFERS FROM MINIPHASE
226-
typeTraverser(_key.unusedDataApply).traverse(t.tpe)
226+
typeTraverser(unusedDataApply).traverse(t.tpe)
227227
traverseChildren(tree)(using newCtx)
228228
case _ =>
229229
//! DIFFERS FROM MINIPHASE
@@ -233,9 +233,14 @@ class CheckUnused extends MiniPhase:
233233

234234
/** This is a type traverser which catch some special Types not traversed by the term traverser above */
235235
private def typeTraverser(dt: (UnusedData => Any) => Unit)(using Context) = new TypeTraverser:
236-
override def traverse(tp: Type): Unit = tp match
237-
case AnnotatedType(_, annot) => dt(_.registerUsed(annot.symbol, None))
238-
case _ => traverseChildren(tp)
236+
override def traverse(tp: Type): Unit =
237+
if tp.typeSymbol.exists then dt(_.registerUsed(tp.typeSymbol, Some(tp.typeSymbol.name)))
238+
tp match
239+
case AnnotatedType(_, annot) =>
240+
dt(_.registerUsed(annot.symbol, None))
241+
traverseChildren(tp)
242+
case _ =>
243+
traverseChildren(tp)
239244

240245
/** This traverse the annotations of the symbol */
241246
private def traverseAnnotations(sym: Symbol)(using Context): Unit =
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// scalac: -Wunused:imports
2+
3+
trait Outer:
4+
trait Used
5+
trait Unused
6+
7+
object Test {
8+
val outer: Outer = ???
9+
import outer.{Used, Unused} // error
10+
def foo(x: Any): Used = x.asInstanceOf[Used]
11+
}
12+
13+
trait Outer1:
14+
trait UnusedToo1
15+
trait Unused1
16+
def unusedToo1: UnusedToo1
17+
18+
object Test1 {
19+
val outer1: Outer1 = ???
20+
import outer1.{Unused1, UnusedToo1} // error // error
21+
def foo() = outer1.unusedToo1 // in this case UnusedToo1 is not used explicitly, only inferred
22+
}

0 commit comments

Comments
 (0)