@@ -5,6 +5,7 @@ package init
55
66import dotty .tools .dotc ._
77import ast .tpd
8+ import tpd ._
89
910import dotty .tools .dotc .core ._
1011import Contexts ._
@@ -15,51 +16,54 @@ import StdNames._
1516import dotty .tools .dotc .transform ._
1617import Phases ._
1718
18-
1919import scala .collection .mutable
2020
21+ import Semantic ._
2122
2223class Checker extends Phase {
23- import tpd ._
2424
2525 val phaseName = " initChecker"
2626
27- private val semantic = new Semantic
28-
2927 override val runsAfter = Set (Pickler .name)
3028
3129 override def isEnabled (using Context ): Boolean =
3230 super .isEnabled && ctx.settings.YcheckInit .value
3331
3432 override def runOn (units : List [CompilationUnit ])(using Context ): List [CompilationUnit ] =
35- units.foreach { unit => traverser.traverse(unit.tpdTree) }
36- super .runOn(units)
33+ val checkCtx = ctx.fresh.setPhase(this .start)
34+ Semantic .withInitialState {
35+ val traverser = new InitTreeTraverser ()
36+ units.foreach { unit => traverser.traverse(unit.tpdTree) }
37+ given Context = checkCtx
38+ Semantic .check()
39+ super .runOn(units)
40+ }
41+
42+ def run (using Context ): Unit = {
43+ // ignore, we already called `Semantic.check()` in `runOn`
44+ }
3745
38- val traverser = new TreeTraverser {
46+ class InitTreeTraverser ( using WorkList ) extends TreeTraverser {
3947 override def traverse (tree : Tree )(using Context ): Unit =
4048 traverseChildren(tree)
4149 tree match {
42- case tdef : MemberDef =>
50+ case mdef : MemberDef =>
4351 // self-type annotation ValDef has no symbol
44- if tdef.name != nme.WILDCARD then
45- tdef.symbol.defTree = tree
46- case _ =>
47- }
48- }
52+ if mdef.name != nme.WILDCARD then
53+ mdef.symbol.defTree = tree
4954
50- override def run (using Context ): Unit = {
51- val unit = ctx.compilationUnit
52- unit.tpdTree.foreachSubTree {
53- case tdef : TypeDef if tdef.isClassDef =>
54- transformTypeDef(tdef)
55+ mdef match
56+ case tdef : TypeDef if tdef.isClassDef =>
57+ val cls = tdef.symbol.asClass
58+ val thisRef = ThisRef (cls)
59+ if shouldCheckClass(cls) then Semantic .addTask(thisRef)
60+ case _ =>
5561
56- case _ =>
57- }
62+ case _ =>
63+ }
5864 }
5965
60-
61- private def transformTypeDef (tree : TypeDef )(using Context ): tpd.Tree = {
62- val cls = tree.symbol.asClass
66+ private def shouldCheckClass (cls : ClassSymbol )(using Context ) = {
6367 val instantiable : Boolean =
6468 cls.is(Flags .Module ) ||
6569 ! cls.isOneOf(Flags .AbstractOrTrait ) && {
@@ -71,21 +75,6 @@ class Checker extends Phase {
7175 }
7276
7377 // A concrete class may not be instantiated if the self type is not satisfied
74- if (instantiable && cls.enclosingPackageClass != defn.StdLibPatchesPackage .moduleClass) {
75- import semantic ._
76- val tpl = tree.rhs.asInstanceOf [Template ]
77- val thisRef = ThisRef (cls).ensureExists
78-
79- val paramValues = tpl.constr.termParamss.flatten.map(param => param.symbol -> Hot ).toMap
80-
81- given Promoted = Promoted .empty
82- given Trace = Trace .empty
83- given Env = Env (paramValues)
84-
85- val res = eval(tpl, thisRef, cls)
86- res.errors.foreach(_.issue)
87- }
88-
89- tree
78+ instantiable && cls.enclosingPackageClass != defn.StdLibPatchesPackage .moduleClass
9079 }
9180}
0 commit comments