Skip to content

Commit f1163df

Browse files
committed
fix #12919: case class companion is never a singleton mirror
1 parent 9ed0762 commit f1163df

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

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)) makeSingletonMirror()
595+
if (clazz.is(Case) && !linked.isGenericProduct) 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

+1-1
Original file line numberDiff line numberDiff line change
@@ -282,7 +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-
if module.info.classSymbol.is(Scala2x) then
285+
if module.info.classSymbol.is(Scala2x) || module.companionClass.isGenericProduct then
286286
val mirrorType = mirrorCore(defn.Mirror_SingletonProxyClass, mirroredType, mirroredType, module.name, formal)
287287
val mirrorRef = New(defn.Mirror_SingletonProxyClass.typeRef, modulePath :: Nil)
288288
mirrorRef.cast(mirrorType)

tests/run/i12919.scala

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
case class Normal(value: String)
2+
object Normal
3+
4+
case class ClassWithCaseCompanion(value: String)
5+
case object ClassWithCaseCompanion
6+
7+
def instantiate[T](product: Product)(implicit mirror: scala.deriving.Mirror.ProductOf[T]) =
8+
mirror.fromProduct(product)
9+
10+
@main def Test: Unit = {
11+
assert(instantiate[Normal](Tuple1("a")) == Normal("a")) // works as expected
12+
13+
assert(instantiate[ClassWithCaseCompanion.type](EmptyTuple) == ClassWithCaseCompanion) // works as expected
14+
15+
val c = instantiate[ClassWithCaseCompanion](Tuple1("b")) // throws java.lang.ClassCastException: class ClassWithCaseCompanion$ cannot be cast to class ClassWithCaseCompanion
16+
assert(c == ClassWithCaseCompanion("b")) // desired behaviour
17+
18+
val d = instantiate[ClassWithCaseCompanion.type](EmptyTuple)
19+
assert(d == ClassWithCaseCompanion)
20+
}

0 commit comments

Comments
 (0)