Skip to content

Commit f3e8d83

Browse files
committed
alternative: do not change parent type of companion
1 parent d652f07 commit f3e8d83

File tree

6 files changed

+19
-36
lines changed

6 files changed

+19
-36
lines changed

compiler/src/dotty/tools/dotc/transform/SymUtils.scala

+3-14
Original file line numberDiff line numberDiff line change
@@ -117,23 +117,12 @@ object SymUtils:
117117
self.isOneOf(FinalOrInline, butNot = Mutable)
118118
&& (!self.is(Method) || self.is(Accessor))
119119

120-
/** This module must use a `Mirror.SingletonProxy` for its mirror if:
121-
* - it is Scala 2 defined
122-
* - the companion class is a generic product or generic sum and would cache
123-
* its mirror in this module.
124-
*/
125-
def requiresSingletonProxyMirror(using Context): Boolean =
126-
self.is(Scala2x) || {
127-
val cls = self.companionClass
128-
cls.isGenericProduct
129-
|| cls.useCompanionAsSumMirror && cls.isGenericSum(self)
130-
}
131-
132120
def useCompanionAsSumMirror(using Context): Boolean =
133121
def companionExtendsSum(using Context): Boolean =
134122
self.linkedClass.isSubClass(defn.Mirror_SumClass)
135-
self.linkedClass.exists
136-
&& !self.is(Scala2x)
123+
!self.is(Scala2x)
124+
&& self.linkedClass.exists
125+
&& !self.linkedClass.is(Case)
137126
&& (
138127
// If the sum type is compiled from source, and `self` is a "generic sum"
139128
// then its companion object will become a sum mirror in `posttyper`. (This method

compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
592592
}
593593

594594
if (clazz.is(Module)) {
595-
if (clazz.is(Case) && !clazz.requiresSingletonProxyMirror) makeSingletonMirror()
595+
if (clazz.is(Case)) makeSingletonMirror()
596596
else if (linked.isGenericProduct) makeProductMirror(linked)
597597
else if (linked.isGenericSum(clazz)) makeSumMirror(linked)
598598
else if (linked.is(Sealed))

compiler/src/dotty/tools/dotc/typer/Synthesizer.scala

+2-5
Original file line numberDiff line numberDiff line change
@@ -282,10 +282,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
282282
if mirroredType.termSymbol.is(CaseVal) then
283283
val module = mirroredType.termSymbol
284284
val modulePath = pathFor(mirroredType).withSpan(span)
285-
val requiresProxy =
286-
val mClass = module.info.classSymbol
287-
mClass.is(Module) && mClass.requiresSingletonProxyMirror
288-
if requiresProxy then
285+
if module.info.classSymbol.is(Scala2x) then
289286
val mirrorType = mirrorCore(defn.Mirror_SingletonProxyClass, mirroredType, mirroredType, module.name, formal)
290287
val mirrorRef = New(defn.Mirror_SingletonProxyClass.typeRef, modulePath :: Nil)
291288
mirrorRef.cast(mirrorType)
@@ -310,7 +307,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
310307
.refinedWith(tpnme.MirroredElemTypes, TypeAlias(elemsType))
311308
.refinedWith(tpnme.MirroredElemLabels, TypeAlias(elemsLabels))
312309
val mirrorRef =
313-
if (cls.is(Scala2x)) anonymousMirror(monoType, ExtendsProductMirror, span)
310+
if (cls.is(Scala2x) || cls.linkedClass.is(Case)) anonymousMirror(monoType, ExtendsProductMirror, span)
314311
else companionPath(mirroredType, span)
315312
mirrorRef.cast(mirrorType)
316313
else EmptyTree

library/src/scala/deriving/Mirror.scala

+1-3
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,7 @@ object Mirror {
3737
def fromProduct(p: scala.Product): MirroredMonoType = this
3838
}
3939

40-
/** A proxy for Scala 2 singletons (which do not inherit `Singleton` directly),
41-
* or case objects with a case class companion
42-
*/
40+
/** A proxy for Scala 2 singletons, which do not inherit `Singleton` directly */
4341
class SingletonProxy(val value: AnyRef) extends Product {
4442
type MirroredMonoType = value.type
4543
type MirroredType = value.type

tests/run/i12919a.scala

+9-10
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
import scala.deriving.Mirror
22

3-
class Standalone
4-
case object Standalone
3+
case class Standalone(i: Int)
4+
object Standalone
55

66
case class WithCompanionCaseClass(i: Int)
77
case object WithCompanionCaseClass
88

99
@main def Test: Unit =
1010

11-
val mStandalone = summon[Mirror.Of[Standalone.type]]
12-
assert(mStandalone eq Standalone) // the object is its own mirror
13-
assert(mStandalone.isInstanceOf[Mirror.Singleton]) // object extends Mirror.Singleton because its its own mirror.
11+
val mStandalone = summon[Mirror.ProductOf[Standalone]]
12+
assert(mStandalone eq Standalone) // the companion object is the mirror for the case class
1413

15-
val mWithCompanion = summon[Mirror.Of[WithCompanionCaseClass.type]]
16-
assert(mWithCompanion ne WithCompanionCaseClass) // the object is not its own mirror
17-
assert(mWithCompanion.isInstanceOf[Mirror.SingletonProxy]) // its companion is a case class, so the mirror is a proxy
18-
assert(!mWithCompanion.isInstanceOf[Mirror.Singleton]) // it can not extend Mirror.Singleton because its companion is a case class.
19-
assert(WithCompanionCaseClass.isInstanceOf[Mirror.Product]) // its companion is a case class, so the mirror is a product.
14+
val mWithCompanion = summon[Mirror.ProductOf[WithCompanionCaseClass]]
15+
assert(mWithCompanion ne WithCompanionCaseClass) // A case object can not be the mirror of a companion case class.
16+
17+
val mWithCompanionCaseObject = summon[Mirror.ProductOf[WithCompanionCaseClass.type]]
18+
assert(mWithCompanionCaseObject eq WithCompanionCaseClass) // A case object is its own mirror.

tests/run/i12919b.scala

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ case object WithCompanionSealedTrait:
99

1010
val mWithCompanionSum = summon[Mirror.SumOf[WithCompanionSealedTrait]]
1111
assert(mWithCompanionSum.ordinal(WithCompanionSealedTrait.FirstChild(1)) == 0)
12-
assert(mWithCompanionSum eq WithCompanionSealedTrait) // case object caches sum mirror of its companion
12+
assert(mWithCompanionSum ne WithCompanionSealedTrait) // A case object can not be the mirror of a companion case class.
1313

1414
val mWithCompanionSingleton = summon[Mirror.ProductOf[WithCompanionSealedTrait.type]]
1515
assert(mWithCompanionSingleton.fromProduct(EmptyTuple) == WithCompanionSealedTrait)
16-
assert(mWithCompanionSingleton.isInstanceOf[Mirror.SingletonProxy])
17-
assert(mWithCompanionSingleton ne WithCompanionSealedTrait) // proxy mirror is never the object itself
16+
assert(mWithCompanionSingleton.isInstanceOf[Mirror.Singleton]) // case object is its own mirror.
17+
assert(mWithCompanionSingleton eq WithCompanionSealedTrait) // case object is its own mirror.

0 commit comments

Comments
 (0)