Skip to content

Commit c735461

Browse files
committed
Mono Mega Phase
1 parent 5bd5043 commit c735461

File tree

4 files changed

+26
-25
lines changed

4 files changed

+26
-25
lines changed

compiler/src/dotty/tools/dotc/Compiler.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import typer.{TyperPhase, RefChecks}
77
import parsing.Parser
88
import Phases.Phase
99
import transform.*
10-
import dotty.tools.backend
1110
import backend.jvm.{CollectSuperCalls, GenBCode}
1211
import localopt.StringInterpolatorOpt
1312

@@ -34,8 +33,7 @@ class Compiler {
3433
protected def frontendPhases: List[List[Phase]] =
3534
List(new Parser) :: // Compiler frontend: scanner, parser
3635
List(new TyperPhase) :: // Compiler frontend: namer, typer
37-
List(new CheckUnused.PostTyper) :: // Check for unused elements
38-
List(new CheckShadowing) :: // Check shadowing elements
36+
List(new CheckUnused.PostTyper, new CheckShadowing) :: // Check for unused, shadowed elements
3937
List(new YCheckPositions) :: // YCheck positions
4038
List(new sbt.ExtractDependencies) :: // Sends information on classes' dependencies to sbt via callbacks
4139
List(new semanticdb.ExtractSemanticDB.ExtractSemanticInfo) :: // Extract info into .semanticdb files

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

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -49,26 +49,22 @@ class CheckShadowing extends MiniPhase:
4949

5050
override def description: String = CheckShadowing.description
5151

52+
override def isEnabled(using Context): Boolean = ctx.settings.Wshadow.value.nonEmpty
53+
5254
override def isRunnable(using Context): Boolean =
53-
super.isRunnable &&
54-
ctx.settings.Wshadow.value.nonEmpty &&
55-
!ctx.isJava
55+
super.isRunnable && ctx.settings.Wshadow.value.nonEmpty && !ctx.isJava
5656

57-
// Setup before the traversal
5857
override def prepareForUnit(tree: tpd.Tree)(using Context): Context =
5958
val data = ShadowingData()
6059
val fresh = ctx.fresh.setProperty(_key, data)
6160
shadowingDataApply(sd => sd.registerRootImports())(using fresh)
6261

63-
// Reporting on traversal's end
6462
override def transformUnit(tree: tpd.Tree)(using Context): tpd.Tree =
6563
shadowingDataApply(sd =>
6664
reportShadowing(sd.getShadowingResult)
6765
)
6866
tree
6967

70-
// MiniPhase traversal :
71-
7268
override def prepareForPackageDef(tree: tpd.PackageDef)(using Context): Context =
7369
shadowingDataApply(sd => sd.inNewScope())
7470
ctx
@@ -94,14 +90,14 @@ class CheckShadowing extends MiniPhase:
9490
if tree.symbol.isAliasType then // if alias, the parent is the current symbol
9591
nestedTypeTraverser(tree.symbol).traverse(tree.rhs)
9692
if tree.symbol.is(Param) then // if param, the parent is up
97-
val owner = tree.symbol.owner
98-
val parent = if (owner.isConstructor) then owner.owner else owner
99-
nestedTypeTraverser(parent).traverse(tree.rhs)(using ctx.outer)
100-
shadowingDataApply(sd => sd.registerCandidate(parent, tree))
93+
val enclosing =
94+
val owner = tree.symbol.ownersIterator.dropWhile(_.is(Param)).next()
95+
if owner.isConstructor then owner.owner else owner
96+
nestedTypeTraverser(enclosing).traverse(tree.rhs)(using ctx.outer)
97+
shadowingDataApply(_.registerCandidate(enclosing, tree))
10198
else
10299
ctx
103100

104-
105101
override def transformPackageDef(tree: tpd.PackageDef)(using Context): tpd.Tree =
106102
shadowingDataApply(sd => sd.outOfScope())
107103
tree
@@ -115,13 +111,16 @@ class CheckShadowing extends MiniPhase:
115111
tree
116112

117113
override def transformTypeDef(tree: tpd.TypeDef)(using Context): tpd.Tree =
118-
if tree.symbol.is(Param) && isValidTypeParamOwner(tree.symbol.owner) then // Do not register for constructors the work is done for the Class owned equivalent TypeDef
119-
shadowingDataApply(sd => sd.computeTypeParamShadowsFor(tree.symbol.owner)(using ctx.outer))
120-
if tree.symbol.isAliasType then // No need to start outer here, because the TypeDef reached here it's already the parent
114+
// Do not register for constructors the work is done for the Class owned equivalent TypeDef
115+
if tree.symbol.is(Param) then
116+
val owner = tree.symbol.ownersIterator.dropWhile(_.is(Param)).next()
117+
if isValidTypeParamOwner(owner) then
118+
shadowingDataApply(_.computeTypeParamShadowsFor(owner)(using ctx.outer))
119+
// No need to start outer here, because the TypeDef reached here it's already the parent
120+
if tree.symbol.isAliasType then
121121
shadowingDataApply(sd => sd.computeTypeParamShadowsFor(tree.symbol)(using ctx))
122122
tree
123123

124-
// Helpers :
125124
private def isValidTypeParamOwner(owner: Symbol)(using Context): Boolean =
126125
!owner.isConstructor && !owner.is(Synthetic) && !owner.is(Exported)
127126

@@ -310,4 +309,3 @@ object CheckShadowing:
310309
case class ShadowResult(warnings: List[ShadowWarning])
311310

312311
end CheckShadowing
313-

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ class CheckUnused private (phaseMode: CheckUnused.PhaseMode, suffix: String, _ke
8888
tree
8989

9090
override def transformApply(tree: Apply)(using Context): Tree =
91-
//println(s"APPLY ${tree.show}")
9291
tree
9392

9493
override def transformTyped(tree: Typed)(using Context): Tree =
@@ -117,7 +116,6 @@ class CheckUnused private (phaseMode: CheckUnused.PhaseMode, suffix: String, _ke
117116
override def prepareForTypeTree(tree: TypeTree)(using Context): Context = ctx
118117

119118
override def transformTypeTree(tree: TypeTree)(using Context): tree.type =
120-
//println(s"TYPETREE ${tree.getClass} ${tree.show} or $tree")
121119
tree.tpe match
122120
case AnnotatedType(_, annot) => transformAllDeep(annot.tree)
123121
case _ =>
@@ -134,7 +132,6 @@ class CheckUnused private (phaseMode: CheckUnused.PhaseMode, suffix: String, _ke
134132
ud.addIgnoredUsage(tree.symbol)
135133

136134
override def transformValDef(tree: ValDef)(using Context): tree.type =
137-
//println(s"VAL ${tree.name} ${tree.show} tpt ${tree.tpt.show} is a ${tree.tpt.getClass}")
138135
preparing:
139136
traverseAnnotations(tree.symbol)
140137
if !tree.symbol.is(Module) then // do not register the ValDef generated for `object`
@@ -209,8 +206,6 @@ class CheckUnused private (phaseMode: CheckUnused.PhaseMode, suffix: String, _ke
209206
selector.bound match
210207
case untpd.TypedSplice(bound) => transformAllDeep(bound)
211208
case _ =>
212-
case _: InferredTypeTree =>
213-
//println(s"INF ${tree.getClass} ${tree.show}")
214209
case AppliedTypeTree(tpt, args) =>
215210
transformAllDeep(tpt)
216211
args.foreach(transformAllDeep)
@@ -227,6 +222,7 @@ class CheckUnused private (phaseMode: CheckUnused.PhaseMode, suffix: String, _ke
227222
transformAllDeep(hi)
228223
transformAllDeep(alias)
229224
case tree: NamedArg => transformAllDeep(tree.arg)
225+
case _: InferredTypeTree =>
230226
case _ if tree.isType =>
231227
//println(s"OTHER TYPE ${tree.getClass} ${tree.show}")
232228
case _ =>

tests/warn/i19657-mega.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//> using options -Wshadow:type-parameter-shadow -Wunused:all
2+
3+
class F[X, M[N[X]]]:
4+
private def x[X] = toString // warn // warn
5+
6+
// the first is spurious
7+
// at 3: Type parameter X for type M shadows the type defined by type X in class F
8+
// at 4: Type parameter X for method x shadows the type defined by type X in class F
9+
// at 4: unused private member

0 commit comments

Comments
 (0)