aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala4
-rw-r--r--src/dotty/tools/dotc/transform/RestoreScopes.scala14
-rw-r--r--src/dotty/tools/dotc/transform/TreeChecker.scala14
-rw-r--r--src/dotty/tools/dotc/transform/ValueClasses.scala4
4 files changed, 34 insertions, 2 deletions
diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala
index dab84bb5f..47342cb56 100644
--- a/src/dotty/tools/dotc/core/Symbols.scala
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -161,12 +161,14 @@ trait Symbols { this: Context =>
owner.thisType, modcls, parents, decls, TermRef.withSymAndName(owner.thisType, module, name)),
privateWithin, coord, assocFile)
+ val companionMethodFlags = Flags.Synthetic | Flags.Private | Flags.Method
+
def synthesizeCompanionMethod(name: Name, target: SymDenotation, owner: SymDenotation)(implicit ctx: Context) =
if (owner.exists && target.exists && !owner.isAbsent && !target.isAbsent) {
val existing = owner.unforcedDecls.lookup(name)
existing.orElse{
- ctx.newSymbol(owner.symbol, name, Flags.Synthetic | Flags.Private, ExprType(target.typeRef))
+ ctx.newSymbol(owner.symbol, name, companionMethodFlags , ExprType(target.typeRef))
}
} else NoSymbol
diff --git a/src/dotty/tools/dotc/transform/RestoreScopes.scala b/src/dotty/tools/dotc/transform/RestoreScopes.scala
index 3a168b1fe..fe24186ac 100644
--- a/src/dotty/tools/dotc/transform/RestoreScopes.scala
+++ b/src/dotty/tools/dotc/transform/RestoreScopes.scala
@@ -13,6 +13,7 @@ import ast.Trees._
import NameOps._
import typer.Mode
import TreeTransforms.TransformerInfo
+import StdNames._
/** The preceding lambda lift and flatten phases move symbols to different scopes
* and rename them. This miniphase cleans up afterwards and makes sure that all
@@ -33,6 +34,19 @@ class RestoreScopes extends MiniPhaseTransform with IdentityDenotTransformer { t
// For top-level classes this does nothing.
val cls = tree.symbol.asClass
val pkg = cls.owner.asClass
+
+ // Bring back companion links
+ val companionClass = cls.info.decls.lookup(nme.COMPANION_CLASS_METHOD)
+ val companionModule = cls.info.decls.lookup(nme.COMPANION_MODULE_METHOD)
+
+ if (companionClass.exists) {
+ restoredDecls.enter(companionClass)
+ }
+
+ if (companionModule.exists) {
+ restoredDecls.enter(companionModule)
+ }
+
pkg.enter(cls)
val cinfo = cls.classInfo
tree.symbol.copySymDenotation(
diff --git a/src/dotty/tools/dotc/transform/TreeChecker.scala b/src/dotty/tools/dotc/transform/TreeChecker.scala
index 43e1ce8a6..1661f7576 100644
--- a/src/dotty/tools/dotc/transform/TreeChecker.scala
+++ b/src/dotty/tools/dotc/transform/TreeChecker.scala
@@ -56,6 +56,18 @@ class TreeChecker extends Phase with SymTransformer {
registry(name) = sym
}
+ def checkCompanion(symd: SymDenotation)(implicit ctx: Context): Unit = {
+ val cur = symd.linkedClass
+ val prev = ctx.atPhase(ctx.phase.prev) {
+ ct => {
+ implicit val ctx: Context = ct.withMode(Mode.FutureDefsOK)
+ symd.symbol.linkedClass
+ }
+ }
+
+ if (prev.exists)
+ assert(cur.exists, i"companion disappeared from $symd")
+ }
def transformSym(symd: SymDenotation)(implicit ctx: Context): SymDenotation = {
val sym = symd.symbol
@@ -69,6 +81,8 @@ class TreeChecker extends Phase with SymTransformer {
testDuplicate(sym, seenClasses, "class")
}
+ checkCompanion(symd)
+
symd
}
diff --git a/src/dotty/tools/dotc/transform/ValueClasses.scala b/src/dotty/tools/dotc/transform/ValueClasses.scala
index ab4bba94e..a7a0db97c 100644
--- a/src/dotty/tools/dotc/transform/ValueClasses.scala
+++ b/src/dotty/tools/dotc/transform/ValueClasses.scala
@@ -7,6 +7,7 @@ import Symbols._
import SymDenotations._
import Contexts._
import Flags._
+import StdNames._
/** Methods that apply to user-defined value classes */
object ValueClasses {
@@ -22,7 +23,8 @@ object ValueClasses {
isDerivedValueClass(d.owner) &&
!d.isConstructor &&
!d.is(SuperAccessor) &&
- !d.is(Macro)
+ !d.is(Macro) &&
+ !(d.name eq nme.COMPANION_MODULE_METHOD)
/** The member that of a derived value class that unboxes it. */
def valueClassUnbox(d: ClassDenotation)(implicit ctx: Context): Symbol =