File tree 6 files changed +69
-3
lines changed
compiler/src/dotty/tools/dotc
6 files changed +69
-3
lines changed Original file line number Diff line number Diff line change @@ -120,8 +120,9 @@ object SymUtils:
120
120
def useCompanionAsSumMirror (using Context ): Boolean =
121
121
def companionExtendsSum (using Context ): Boolean =
122
122
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 )
125
126
&& (
126
127
// If the sum type is compiled from source, and `self` is a "generic sum"
127
128
// 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):
307
307
.refinedWith(tpnme.MirroredElemTypes , TypeAlias (elemsType))
308
308
.refinedWith(tpnme.MirroredElemLabels , TypeAlias (elemsLabels))
309
309
val mirrorRef =
310
- if (cls.is(Scala2x )) anonymousMirror(monoType, ExtendsProductMirror , span)
310
+ if (cls.is(Scala2x ) || cls.linkedClass.is( Case ) ) anonymousMirror(monoType, ExtendsProductMirror , span)
311
311
else companionPath(mirroredType, span)
312
312
mirrorRef.cast(mirrorType)
313
313
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