Skip to content

Commit 1a5b137

Browse files
committed
More friendly trace for collected transitive dependencies
1 parent 5787e5c commit 1a5b137

File tree

2 files changed

+26
-26
lines changed

2 files changed

+26
-26
lines changed

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -229,15 +229,15 @@ object Checking {
229229

230230
case hot: Hot =>
231231
val target = resolve(hot.classSymbol, sym)
232-
state.dependencies += StaticCall(hot.classSymbol, target)(pot.source)
232+
state.dependencies += StaticCall(hot.classSymbol, target)(state.path)
233233
Errors.empty
234234

235235
case obj: Global =>
236236
val target = resolve(obj.moduleClass, sym)
237237
if obj.enclosingClass == state.thisClass && obj.moduleClass == state.thisClass then
238238
check(MethodCall(ThisRef()(obj.source), target)(eff.source))
239239
else
240-
state.dependencies += StaticCall(obj.moduleClass, target)(pot.source)
240+
state.dependencies += StaticCall(obj.moduleClass, target)(state.path)
241241
Errors.empty
242242

243243
case _: Cold =>
@@ -330,31 +330,31 @@ object Checking {
330330
else PromoteWarm(pot, eff.source, state.path).toErrors
331331

332332
case obj: Global =>
333-
state.dependencies += InstanceUsage(obj.moduleClass, obj.moduleClass)(pot.source)
333+
state.dependencies += InstanceUsage(obj.moduleClass, obj.moduleClass)(state.path)
334334
Errors.empty
335335

336336
case hot: Hot =>
337-
state.dependencies += InstanceUsage(hot.classSymbol, hot.classSymbol)(pot.source)
337+
state.dependencies += InstanceUsage(hot.classSymbol, hot.classSymbol)(state.path)
338338
Errors.empty
339339

340340
case MethodReturn(hot: Hot, sym) =>
341341
val target = resolve(hot.classSymbol, sym)
342-
state.dependencies += ProxyUsage(hot.classSymbol, target)(pot.source)
342+
state.dependencies += ProxyUsage(hot.classSymbol, target)(state.path)
343343
Errors.empty
344344

345345
case MethodReturn(obj: Global, sym) =>
346346
val target = resolve(obj.moduleClass, sym)
347-
state.dependencies += ProxyUsage(obj.moduleClass, target)(pot.source)
347+
state.dependencies += ProxyUsage(obj.moduleClass, target)(state.path)
348348
Errors.empty
349349

350350
case FieldReturn(hot: Hot, sym) =>
351351
val target = resolve(hot.classSymbol, sym)
352-
state.dependencies += ProxyUsage(hot.classSymbol, target)(pot.source)
352+
state.dependencies += ProxyUsage(hot.classSymbol, target)(state.path)
353353
Errors.empty
354354

355355
case FieldReturn(obj: Global, sym) =>
356356
val target = resolve(obj.moduleClass, sym)
357-
state.dependencies += ProxyUsage(obj.moduleClass, target)(pot.source)
357+
state.dependencies += ProxyUsage(obj.moduleClass, target)(state.path)
358358
Errors.empty
359359

360360
case Fun(pots, effs) =>
@@ -386,7 +386,7 @@ object Checking {
386386
private def checkAccessGlobal(eff: AccessGlobal)(using state: State): Errors =
387387
val obj = eff.potential
388388
if obj.enclosingClass != obj.moduleClass then
389-
state.dependencies += ObjectAccess(obj.symbol)(eff.source)
389+
state.dependencies += ObjectAccess(obj.symbol)(state.path)
390390
Errors.empty
391391

392392
private def expand(pot: Potential)(using state: State): Summary = trace("expand " + pot.show, init, _.asInstanceOf[Summary].show) {

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

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,17 @@ import scala.collection.mutable
4545
*/
4646
trait Dependency {
4747
def symbol: Symbol
48-
def source: Tree
48+
def source: Vector[Tree]
4949
def show(using Context): String
5050
}
5151

5252
/** Depend on the initialization of another object */
53-
case class ObjectAccess(symbol: Symbol)(val source: Tree) extends Dependency {
53+
case class ObjectAccess(symbol: Symbol)(val source: Vector[Tree]) extends Dependency {
5454
def show(using Context): String = "ObjectAccess(" + symbol.show + ")"
5555
}
5656

5757
/** Depend on usage of an instance, which can be either a class instance or object */
58-
case class InstanceUsage(symbol: ClassSymbol, instanceClass: ClassSymbol)(val source: Tree) extends Dependency {
58+
case class InstanceUsage(symbol: ClassSymbol, instanceClass: ClassSymbol)(val source: Vector[Tree]) extends Dependency {
5959
def show(using Context): String = "InstanceUsage(" + symbol.show + ")"
6060
}
6161

@@ -67,15 +67,15 @@ case class InstanceUsage(symbol: ClassSymbol, instanceClass: ClassSymbol)(val so
6767
* Note: Virtual method resolution should have been performed for the target.
6868
*
6969
*/
70-
case class StaticCall(cls: ClassSymbol, symbol: Symbol)(val source: Tree) extends Dependency {
70+
case class StaticCall(cls: ClassSymbol, symbol: Symbol)(val source: Vector[Tree]) extends Dependency {
7171
def show(using Context): String = "StaticCall(" + cls.show + ", " + symbol.show + ")"
7272
}
7373

7474
/** A static method call result is used
7575
*
7676
* Note: Virtual method resolution should have been performed for the target.
7777
*/
78-
case class ProxyUsage(cls: ClassSymbol, symbol: Symbol)(val source: Tree) extends Dependency {
78+
case class ProxyUsage(cls: ClassSymbol, symbol: Symbol)(val source: Vector[Tree]) extends Dependency {
7979
def show(using Context): String = "ProxyUsage(" + cls.show + ", " + symbol.show + ")"
8080
}
8181

@@ -107,7 +107,7 @@ class CycleChecker(cache: Cache) {
107107
def checkCyclic()(using Context): Unit = {
108108
val state = State(visited = mutable.Set.empty, path = Vector.empty, trace = Vector.empty)
109109
objectsInCurrentRun.foreach { obj =>
110-
val dep = ObjectAccess(obj)(obj.defTree)
110+
val dep = ObjectAccess(obj)(Vector(obj.defTree))
111111
val errors = check(dep)(using ctx, state)
112112
errors.foreach(_.issue)
113113
}
@@ -136,15 +136,15 @@ class CycleChecker(cache: Cache) {
136136
val obj = dep.symbol
137137
if state.path.contains(obj) then
138138
val cycle = state.path.dropWhile(_ != obj)
139-
val trace = state.trace.dropWhile(_.symbol != obj).map(_.source) :+ dep.source
139+
val trace = state.trace.dropWhile(_.symbol != obj).flatMap(_.source) ++ dep.source
140140
if cycle.size > 1 then
141141
CyclicObjectInit(cycle, trace) :: Nil
142142
else
143143
ObjectLeakDuringInit(obj, trace) :: Nil
144144
else
145145
val constr = obj.moduleClass.primaryConstructor
146146
state.visitObject(dep) {
147-
check(StaticCall(constr.owner.asClass, constr)(obj.moduleClass.defTree))
147+
check(StaticCall(constr.owner.asClass, constr)(Vector(obj.moduleClass.defTree)))
148148
}
149149
}
150150

@@ -218,8 +218,8 @@ class CycleChecker(cache: Cache) {
218218
init = true
219219
)
220220

221-
val pot = Hot(dep.cls)(dep.source)
222-
val effs = pot.potentialsOf(dep.symbol)(using env).promote(dep.source)
221+
val pot = Hot(dep.cls)(dep.source.last)
222+
val effs = pot.potentialsOf(dep.symbol)(using env).map(pot => Promote(pot)(pot.source))
223223

224224
val errs = effs.flatMap(Checking.check(_)(using state))
225225
errs.foreach(_.issue)
@@ -250,15 +250,15 @@ class CycleChecker(cache: Cache) {
250250
if vdef.symbol.is(Flags.Lazy) then
251251
traverse(vdef)
252252
else
253-
deps += ProxyUsage(instanceClass, vdef.symbol)(vdef)
253+
deps += ProxyUsage(instanceClass, vdef.symbol)(Vector(vdef))
254254
case stat =>
255255

256256
}
257257

258258
case tree @ Select(inst: New, _) if tree.symbol.isConstructor =>
259259
val cls = inst.tpe.classSymbol.asClass
260-
deps += InstanceUsage(cls, cls)(tree)
261-
deps += StaticCall(cls, tree.symbol)(tree)
260+
deps += InstanceUsage(cls, cls)(Vector(tree))
261+
deps += StaticCall(cls, tree.symbol)(Vector(tree))
262262

263263
case tree: RefTree if tree.isTerm =>
264264
deps ++= analyzeType(tree.tpe, tree, exclude = cls)
@@ -280,7 +280,7 @@ class CycleChecker(cache: Cache) {
280280
// TODO: the traverser might create duplicate entries for parents
281281
tpl.parents.foreach { tree =>
282282
val tp = tree.tpe
283-
deps += InstanceUsage(tp.classSymbol.asClass, instanceClass)(tree)
283+
deps += InstanceUsage(tp.classSymbol.asClass, instanceClass)(Vector(tree))
284284
}
285285

286286
traverser.traverse(tpl)
@@ -293,7 +293,7 @@ class CycleChecker(cache: Cache) {
293293
case tmref: TermRef if isStaticObjectRef(tmref.symbol) =>
294294
val obj = tmref.symbol
295295
val cls = obj.moduleClass.asClass
296-
ObjectAccess(obj)(source) :: InstanceUsage(cls, cls)(source) :: Nil
296+
ObjectAccess(obj)(Vector(source)) :: InstanceUsage(cls, cls)(Vector(source)) :: Nil
297297

298298
case tmref: TermRef =>
299299
analyzeType(tmref.prefix, source, exclude)
@@ -303,7 +303,7 @@ class CycleChecker(cache: Cache) {
303303
then
304304
val cls = tref.symbol.asClass
305305
val obj = cls.sourceModule
306-
ObjectAccess(obj)(source) :: InstanceUsage(cls, cls)(source) :: Nil
306+
ObjectAccess(obj)(Vector(source)) :: InstanceUsage(cls, cls)(Vector(source)) :: Nil
307307
else
308308
Nil
309309

@@ -335,7 +335,7 @@ class CycleChecker(cache: Cache) {
335335
init = true
336336
)
337337

338-
val pot = Hot(dep.cls)(dep.source)
338+
val pot = Hot(dep.cls)(dep.source.last)
339339
val effs = pot.effectsOf(dep.symbol)(using env)
340340

341341
val errs = effs.flatMap(Checking.check(_)(using state))

0 commit comments

Comments
 (0)