Skip to content

Commit 11bd355

Browse files
committed
Merge pull request #1117 from dotty-staging/dont-create-companions
Do not create companions that will be dropped later.
2 parents 6e535f7 + 0f4d74d commit 11bd355

8 files changed

+33
-6
lines changed

src/dotty/tools/dotc/Compiler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class Compiler {
7878
List(new LambdaLift, // in this mini-phase block scopes are incorrect. No phases that rely on scopes should be here
7979
new ElimStaticThis,
8080
new Flatten,
81-
new DropEmptyCompanions,
81+
// new DropEmptyCompanions,
8282
new RestoreScopes),
8383
List(new ExpandPrivate,
8484
new CollectEntryPoints,

src/dotty/tools/dotc/core/Phases.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package core
44
import Periods._
55
import Contexts._
66
import dotty.tools.backend.jvm.{LabelDefs, GenBCode}
7+
import dotty.tools.dotc.core.Symbols.ClassSymbol
78
import util.DotClass
89
import DenotTransformers._
910
import Denotations._
@@ -347,6 +348,10 @@ object Phases {
347348
override def toString = phaseName
348349
}
349350

351+
trait NeedsCompanions {
352+
def isCompanionNeeded(cls: ClassSymbol)(implicit ctx: Context): Boolean
353+
}
354+
350355
/** Replace all instances of `oldPhaseClass` in `current` phases
351356
* by the result of `newPhases` applied to the old phase.
352357
*/

src/dotty/tools/dotc/transform/ExtensionMethods.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import dotty.tools.dotc.ast.{Trees, tpd}
1111
import scala.collection.{ mutable, immutable }
1212
import mutable.ListBuffer
1313
import core._
14-
import Phases.Phase
14+
import dotty.tools.dotc.core.Phases.{NeedsCompanions, Phase}
1515
import Types._, Contexts._, Constants._, Names._, NameOps._, Flags._, DenotTransformers._
1616
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._, Scopes._, Denotations._
1717
import TypeErasure.{ valueErasure, ErasedValueType }
@@ -33,7 +33,7 @@ import SymUtils._
3333
* This is different from the implementation of value classes in Scala 2
3434
* (see SIP-15) which uses `asInstanceOf` which does not typecheck.
3535
*/
36-
class ExtensionMethods extends MiniPhaseTransform with DenotTransformer with FullParameterization { thisTransformer =>
36+
class ExtensionMethods extends MiniPhaseTransform with DenotTransformer with FullParameterization with NeedsCompanions { thisTransformer =>
3737

3838
import tpd._
3939
import ExtensionMethods._
@@ -45,6 +45,10 @@ class ExtensionMethods extends MiniPhaseTransform with DenotTransformer with Ful
4545

4646
override def runsAfterGroupsOf = Set(classOf[FirstTransform]) // need companion objects to exist
4747

48+
def isCompanionNeeded(cls: ClassSymbol)(implicit ctx: Context): Boolean = {
49+
isDerivedValueClass(cls)
50+
}
51+
4852
override def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = ref match {
4953
case moduleClassSym: ClassDenotation if moduleClassSym is ModuleClass =>
5054
moduleClassSym.linkedClass match {

src/dotty/tools/dotc/transform/FirstTransform.scala

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ package transform
33

44
import core._
55
import Names._
6-
import dotty.tools.dotc.transform.TreeTransforms.{AnnotationTransformer, TransformerInfo, MiniPhaseTransform, TreeTransformer}
6+
import dotty.tools.dotc.ast.tpd
7+
import dotty.tools.dotc.core.Phases.NeedsCompanions
8+
import dotty.tools.dotc.transform.TreeTransforms._
79
import ast.Trees._
810
import Flags._
911
import Types._
@@ -32,6 +34,16 @@ class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer wi
3234

3335
override def phaseName = "firstTransform"
3436

37+
private var addCompanionPhases: List[NeedsCompanions] = _
38+
39+
def needsCompanion(cls: ClassSymbol)(implicit ctx: Context) =
40+
addCompanionPhases.exists(_.isCompanionNeeded(cls))
41+
42+
override def prepareForUnit(tree: tpd.Tree)(implicit ctx: Context): TreeTransform = {
43+
addCompanionPhases = ctx.phasePlan.flatMap(_ collect { case p: NeedsCompanions => p })
44+
this
45+
}
46+
3547
def transformInfo(tp: Type, sym: Symbol)(implicit ctx: Context): Type = tp
3648

3749
override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = tree match {
@@ -80,7 +92,7 @@ class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer wi
8092
}
8193

8294
def addMissingCompanions(stats: List[Tree]): List[Tree] = stats map {
83-
case stat: TypeDef if singleClassDefs contains stat.name =>
95+
case stat: TypeDef if (singleClassDefs contains stat.name) && needsCompanion(stat.symbol.asClass) =>
8496
val objName = stat.name.toTermName
8597
val nameClash = stats.exists {
8698
case other: MemberDef =>

src/dotty/tools/dotc/transform/LazyVals.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package dotty.tools.dotc
22
package transform
33

4+
import dotty.tools.dotc.core.Phases.NeedsCompanions
45
import dotty.tools.dotc.typer.Mode
56

67
import scala.collection.mutable
@@ -23,7 +24,7 @@ import dotty.tools.dotc.core.SymDenotations.SymDenotation
2324
import dotty.tools.dotc.core.DenotTransformers.{SymTransformer, IdentityDenotTransformer, DenotTransformer}
2425
import Erasure.Boxing.adaptToType
2526

26-
class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
27+
class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer with NeedsCompanions {
2728
import LazyVals._
2829

2930
import tpd._
@@ -46,6 +47,11 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
4647
* before this phase starts processing same tree */
4748
override def runsAfter = Set(classOf[Mixin])
4849

50+
def isCompanionNeeded(cls: ClassSymbol)(implicit ctx: Context): Boolean = {
51+
def hasLazyVal(x: ClassSymbol) = x.classInfo.membersBasedOnFlags(Flags.Lazy, excludedFlags = Flags.EmptyFlags).nonEmpty
52+
hasLazyVal(cls) || cls.mixins.exists(hasLazyVal)
53+
}
54+
4955
override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree =
5056
transformLazyVal(tree)
5157

0 commit comments

Comments
 (0)