Skip to content

Commit 8672bb1

Browse files
committed
cleanup, no intended functional change
1 parent 2814579 commit 8672bb1

File tree

1 file changed

+50
-33
lines changed

1 file changed

+50
-33
lines changed

src/compiler/scala/tools/nsc/transform/Fields.scala

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -339,29 +339,34 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
339339
}
340340
}
341341

342-
private def transformStat(templateSym: Symbol)(stat: Tree): List[Tree] = {
343-
val clazz = templateSym.owner
342+
private def transformStat(exprOwner: Symbol)(stat: Tree): List[Tree] = {
343+
val clazz = currentOwner
344+
val statSym = stat.symbol
345+
346+
// println(s"transformStat $statSym in ${exprOwner.ownerChain}")
347+
// currentRun.trackerFactory.snapshot()
344348

345-
// TODO do we need to .changeOwner(statSym -> owner)) `rhs` before transforming?
346-
// changing owners as proposed above causes a stackoverflow in uncurry when bootstrapping
347-
// maybe go from statSym -> statSym.owner?
348-
// there's another (conflicting) issue when compiling scala.util.Properties,
349-
// where some references from the impl class are still pointing to the trait interface, not the impl class
350-
def initEffect(rhs: Tree, assignSym: Symbol) =
351-
if (assignSym eq NoSymbol) rhs
349+
// TODO: which symbol should own `rhs`, as the expression is lifted from `statSym` to the class's template?
350+
// Normally, the local dummy (`exprOwner`) is the owner for stats in the template (not `clazz`!)
351+
// when we get owners wrong, the following fails:
352+
// - stackoverflow in uncurry when bootstrapping
353+
// - compiling scala.util.Properties,
354+
// where some references from the impl class are still pointing to the trait interface, not the impl class
355+
// - test/files/trait-defaults/ultimate-nesting.scala,
356+
// where a nested module class is separated from its module, as well as from the `settings` reference
357+
def initEffect(rhs: Tree, assignSym: Symbol) = {
358+
// println(s"initEffect: owner $statSym --> $exprOwner (currentOwner= $currentOwner)")
359+
// println(s"initEffect for $assignSym is $rhs")
360+
361+
val lifted = atOwner(exprOwner)(super.transform(rhs.changeOwner(statSym -> exprOwner)))
362+
363+
if (assignSym eq NoSymbol) lifted
352364
else localTyper.typedPos(rhs.pos) {
353365
val qual = Select(This(clazz), assignSym)
354-
if (assignSym.isSetter) Apply(qual, List(rhs))
355-
else Assign(qual, rhs)
366+
if (assignSym.isSetter) Apply(qual, List(lifted))
367+
else Assign(qual, lifted)
356368
}
357-
358-
val statSym = stat.symbol
359-
// println(s"transformStat $statSym in ${templateSym.ownerChain}")
360-
361-
// `clazz` is not the right owner, local dummy is more accurate at this phase,
362-
// since it's the symbol of the template and thus the owner of template statements
363-
// currentRun.trackerFactory.snapshot()
364-
def lifted(rhs: Tree) = super.transform(rhs.changeOwner(statSym -> templateSym))
369+
}
365370

366371
stat match {
367372
case DefDef(_, _, _, _, _, rhs) if (rhs ne EmptyTree) && (statSym hasFlag ACCESSOR) && !(statSym hasFlag LAZY) =>
@@ -371,7 +376,7 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
371376
// TODO: consolidate with ValDef case
372377
if (clazz.isTrait) {
373378
// there's a synthetic setter if val is not mutable (symbol is created in info transform)
374-
if (fieldMemoization.effectful) deriveDefDef(stat)(getterRhs) :: initEffect(lifted(rhs), fieldMemoization.assignSym) :: Nil
379+
if (fieldMemoization.effectful) deriveDefDef(stat)(getterRhs) :: initEffect(rhs, fieldMemoization.assignSym) :: Nil
375380
else stat :: Nil
376381
} else (
377382
// regular getter -- field will be preserved (see case ValDef)
@@ -386,25 +391,37 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
386391
case ValDef(mods, _, _, rhs) if (rhs ne EmptyTree) && !(statSym hasFlag LAZY) && !(mods hasFlag PRESUPER) =>
387392
val fieldMemoization = fieldMemoizationIn(statSym, clazz)
388393

389-
if (fieldMemoization.needsField) deriveValDef(stat)(_ => EmptyTree) :: initEffect(lifted(rhs), fieldMemoization.assignSym) :: Nil
390-
else if (fieldMemoization.effectOnly) initEffect(lifted(rhs), NoSymbol) :: Nil // drop the val entirely -- it could not have been referenced outside accesors
394+
if (fieldMemoization.needsField) deriveValDef(stat)(_ => EmptyTree) :: initEffect(rhs, fieldMemoization.assignSym) :: Nil
395+
else if (fieldMemoization.effectOnly) initEffect(rhs, NoSymbol) :: Nil // drop the val entirely -- it could not have been referenced outside accesors
391396
else Nil
392397

393-
case tree => List(super.transform(tree))
398+
// case Template(parents, self, body) =>
399+
// treeCopy.Template(tree, transformTrees(parents), transformValDef(self), transformStats(body, tree.symbol))
400+
401+
case tree => List(
402+
if (exprOwner != currentOwner && tree.isTerm) atOwner(exprOwner)(super.transform(tree))
403+
else super.transform(tree)
404+
)
394405
}
395406
}
396407

397-
override def transformTemplate(tree: Template): Template = {
398-
// println(s"transforming stats in ${currentOwner}")
399-
// Skip interfaces (they have no concrete methods, so no work to be done)
400-
if (!currentOwner.isClass || currentOwner.isPackageClass || currentOwner.isInterface) super.transformTemplate(tree)
408+
override def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] =
409+
if (!currentOwner.isClass || currentOwner.isPackageClass || currentOwner.isInterface) super.transformStats(stats, exprOwner)
401410
else afterOwnPhase {
402-
currentOwner.info // TODO remove -- for debugging
403-
deriveTemplate(tree)(stats => {
404-
val templateSym = tree.symbol
405-
fieldsAndAccessors(templateSym) ++ stats.flatMap(transformStat(templateSym))
406-
})
411+
fieldsAndAccessors(exprOwner) ++ (stats flatMap transformStat(exprOwner))
407412
}
408-
}
413+
414+
// override def transformTemplate(tree: Template): Template = {
415+
//// println(s"transforming stats in ${currentOwner}")
416+
// // Skip interfaces (they have no concrete methods, so no work to be done)
417+
// else afterOwnPhase {
418+
// currentOwner.info // TODO remove -- for debugging
419+
// deriveTemplate(tree)(stats => {
420+
// val templateSym = tree.symbol
421+
// fieldsAndAccessors(templateSym) ++ stats.flatMap(transformStat(templateSym))
422+
// })
423+
// }
424+
// }
425+
409426
}
410427
}

0 commit comments

Comments
 (0)