Skip to content

Commit

Permalink
fix scala#12919: case class companion is never a singleton mirror
Browse files Browse the repository at this point in the history
  • Loading branch information
bishabosha committed Apr 20, 2022
1 parent 0f207e5 commit 9ebd60b
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
}

if (clazz.is(Module)) {
if (clazz.is(Case)) makeSingletonMirror()
if (clazz.is(Case) && !linked.isGenericProduct) makeSingletonMirror()
else if (linked.isGenericProduct) makeProductMirror(linked)
else if (linked.isGenericSum(clazz)) makeSumMirror(linked)
else if (linked.is(Sealed))
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Synthesizer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
if mirroredType.termSymbol.is(CaseVal) then
val module = mirroredType.termSymbol
val modulePath = pathFor(mirroredType).withSpan(span)
if module.info.classSymbol.is(Scala2x) then
if module.info.classSymbol.is(Scala2x) || module.companionClass.isGenericProduct then
val mirrorType = mirrorCore(defn.Mirror_SingletonProxyClass, mirroredType, mirroredType, module.name, formal)
val mirrorRef = New(defn.Mirror_SingletonProxyClass.typeRef, modulePath :: Nil)
mirrorRef.cast(mirrorType)
Expand Down
20 changes: 20 additions & 0 deletions tests/run/i12919.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
case class Normal(value: String)
object Normal

case class ClassWithCaseCompanion(value: String)
case object ClassWithCaseCompanion

def instantiate[T](product: Product)(implicit mirror: scala.deriving.Mirror.ProductOf[T]) =
mirror.fromProduct(product)

@main def Test: Unit = {
assert(instantiate[Normal](Tuple1("a")) == Normal("a")) // works as expected

assert(instantiate[ClassWithCaseCompanion.type](EmptyTuple) == ClassWithCaseCompanion) // works as expected

val c = instantiate[ClassWithCaseCompanion](Tuple1("b")) // throws java.lang.ClassCastException: class ClassWithCaseCompanion$ cannot be cast to class ClassWithCaseCompanion
assert(c == ClassWithCaseCompanion("b")) // desired behaviour

val d = instantiate[ClassWithCaseCompanion.type](EmptyTuple)
assert(d == ClassWithCaseCompanion)
}

0 comments on commit 9ebd60b

Please # to comment.