Skip to content

Commit abcadcf

Browse files
committed
Handle static objects as outer
1 parent 8c28e9b commit abcadcf

File tree

2 files changed

+40
-12
lines changed

2 files changed

+40
-12
lines changed

compiler/src/dotty/tools/dotc/transform/init/CheckGlobal.scala

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ import printing.SyntaxHighlighting
1212
import reporting.trace
1313
import config.Printers.init
1414

15-
import ast.Trees._
16-
import ast.tpd
15+
import ast.tpd._
1716

1817
import scala.collection.mutable
1918

@@ -37,10 +36,10 @@ import scala.collection.mutable
3736
* compiled projects.
3837
*/
3938
class CheckGlobal {
40-
case class Dependency(sym: Symbol, source: tpd.Tree)
39+
case class Dependency(sym: Symbol, source: Tree)
4140

4241
/** Checking state */
43-
case class State(var visited: Set[Symbol], path: Vector[tpd.Tree], obj: Symbol) {
42+
case class State(var visited: Set[Symbol], path: Vector[Tree], obj: Symbol) {
4443
def cyclicPath(using Context): String = if (path.isEmpty) "" else " Cyclic path:\n" + {
4544
var indentCount = 0
4645
var last: String = ""
@@ -110,29 +109,50 @@ class CheckGlobal {
110109
if (cls.defTree.isEmpty) Nil
111110
else if (summaryCache.contains(cls)) summaryCache(cls)
112111
else {
113-
val cdef = cls.defTree.asInstanceOf[tpd.TypeDef]
114-
val tpl = cdef.rhs.asInstanceOf[tpd.Template]
112+
val cdef = cls.defTree.asInstanceOf[TypeDef]
113+
val tpl = cdef.rhs.asInstanceOf[Template]
115114
var dependencies: List[Dependency] = Nil
116-
val traverser = new tpd.TreeTraverser {
117-
override def traverse(tree: tpd.Tree)(using Context): Unit =
115+
val traverser = new TreeTraverser {
116+
override def traverse(tree: Tree)(using Context): Unit =
118117
tree match {
119-
case tree: tpd.RefTree if isStaticObjectRef(tree.symbol) =>
118+
case tree: RefTree if isStaticObjectRef(tree.symbol) =>
120119
dependencies = Dependency(tree.symbol, tree) :: dependencies
121120

122-
case tdef: tpd.TypeDef =>
121+
case tdef: TypeDef =>
123122
// don't go into nested classes
124123

125-
case tree: tpd.New =>
124+
case tree: New =>
126125
dependencies = Dependency(tree.tpe.classSymbol, tree) :: dependencies
127126

128127
case _ =>
129128
traverseChildren(tree)
130129
}
131130
}
132131

132+
def typeRefOf(tp: Type): TypeRef = tp.dealias.typeConstructor match {
133+
case tref: TypeRef => tref
134+
case hklambda: HKTypeLambda => typeRefOf(hklambda.resType)
135+
}
136+
137+
def addStaticOuterDep(tp: Type, source: Tree): Unit =
138+
tp match
139+
case NoPrefix =>
140+
case tmref: TermRef =>
141+
if isStaticObjectRef(tmref.symbol) then
142+
dependencies = Dependency(tmref.symbol, source) :: dependencies
143+
case ThisType(tref) =>
144+
val obj = tref.symbol.sourceModule
145+
if isStaticObjectRef(obj) then
146+
dependencies = Dependency(obj, source) :: dependencies
147+
case _ =>
148+
throw new Exception("unexpected type: " + tp)
149+
133150
// TODO: the traverser might create duplicate entries for parents
134151
tpl.parents.foreach { tree =>
135-
dependencies = Dependency(tree.tpe.classSymbol, tree) :: dependencies
152+
val tp = tree.tpe
153+
val tref = typeRefOf(tp)
154+
dependencies = Dependency(tp.classSymbol, tree) :: dependencies
155+
addStaticOuterDep(tref.prefix, tree)
136156
}
137157

138158
traverser.traverse(tpl)

tests/init/neg/t9115.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
object D { // error
2+
def aaa = 1 //that’s the reason
3+
class Z (depends: Any)
4+
case object D1 extends Z(aaa) // 'null' when calling D.D1 first time // error
5+
case object D2 extends Z(aaa) // 'null' when calling D.D2 first time // error
6+
println(D1)
7+
println(D2)
8+
}

0 commit comments

Comments
 (0)