File tree Expand file tree Collapse file tree 6 files changed +69
-3
lines changed
compiler/src/dotty/tools/dotc Expand file tree Collapse file tree 6 files changed +69
-3
lines changed Original file line number Diff line number Diff line change @@ -120,8 +120,9 @@ object SymUtils:
120120 def useCompanionAsSumMirror (using Context ): Boolean =
121121 def companionExtendsSum (using Context ): Boolean =
122122 self.linkedClass.isSubClass(defn.Mirror_SumClass )
123- self.linkedClass.exists
124- && ! self.is(Scala2x )
123+ ! self.is(Scala2x )
124+ && self.linkedClass.exists
125+ && ! self.linkedClass.is(Case )
125126 && (
126127 // If the sum type is compiled from source, and `self` is a "generic sum"
127128 // then its companion object will become a sum mirror in `posttyper`. (This method
Original file line number Diff line number Diff line change @@ -307,7 +307,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
307307 .refinedWith(tpnme.MirroredElemTypes , TypeAlias (elemsType))
308308 .refinedWith(tpnme.MirroredElemLabels , TypeAlias (elemsLabels))
309309 val mirrorRef =
310- if (cls.is(Scala2x )) anonymousMirror(monoType, ExtendsProductMirror , span)
310+ if (cls.is(Scala2x ) || cls.linkedClass.is( Case ) ) anonymousMirror(monoType, ExtendsProductMirror , span)
311311 else companionPath(mirroredType, span)
312312 mirrorRef.cast(mirrorType)
313313 else EmptyTree
Original file line number Diff line number Diff line change 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+ }
Original file line number Diff line number Diff line change 1+ import scala .deriving .Mirror
2+
3+ case class Standalone (i : Int )
4+ object Standalone
5+
6+ case class WithCompanionCaseClass (i : Int )
7+ case object WithCompanionCaseClass
8+
9+ @ main def Test : Unit =
10+
11+ val mStandalone = summon[Mirror .ProductOf [Standalone ]]
12+ assert(mStandalone eq Standalone ) // the companion object is the mirror for the case class
13+
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.
Original file line number Diff line number Diff line change 1+ import scala .deriving .Mirror
2+
3+
4+ sealed trait WithCompanionSealedTrait
5+ case object WithCompanionSealedTrait :
6+ case class FirstChild (x : Int ) extends WithCompanionSealedTrait
7+
8+ @ main def Test : Unit =
9+
10+ val mWithCompanionSum = summon[Mirror .SumOf [WithCompanionSealedTrait ]]
11+ assert(mWithCompanionSum.ordinal(WithCompanionSealedTrait .FirstChild (1 )) == 0 )
12+ assert(mWithCompanionSum ne WithCompanionSealedTrait ) // A case object can not be the mirror of a companion case class.
13+
14+ val mWithCompanionSingleton = summon[Mirror .ProductOf [WithCompanionSealedTrait .type ]]
15+ assert(mWithCompanionSingleton.fromProduct(EmptyTuple ) == WithCompanionSealedTrait )
16+ assert(mWithCompanionSingleton.isInstanceOf [Mirror .Singleton ]) // case object is its own mirror.
17+ assert(mWithCompanionSingleton eq WithCompanionSealedTrait ) // case object is its own mirror.
Original file line number Diff line number Diff line change 1+ trait Encoder [T ]
2+ object Encoder :
3+ def derived [T ](using scala.deriving.Mirror .Of [T ]): Encoder [T ] = new Encoder [T ] {}
4+
5+ case object Bar
6+ enum Bar derives Encoder :
7+ case A , B
8+
9+ @ main def Test : Unit =
10+ summon[Encoder [Bar ]]
You can’t perform that action at this time.
0 commit comments