Skip to content

Commit 5edbe57

Browse files
committed
Avoid name clashes by prefixing all type members with Mirrored
We got a community build failure since a companion object acquired a `Label` type member by auto-generating a `Mirror` parent. To avoid name clashes (or at least make thme very unlikely), we now systematically prefix all type fields with `Mirrored`. We probably should do something similar to the auto-generated `ordinal` and `fromProduct` methods.
1 parent 2a92bab commit 5edbe57

File tree

7 files changed

+61
-57
lines changed

7 files changed

+61
-57
lines changed

compiler/src/dotty/tools/dotc/core/StdNames.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -330,20 +330,20 @@ object StdNames {
330330
val Constant: N = "Constant"
331331
val ConstantType: N = "ConstantType"
332332
val doubleHash: N = "doubleHash"
333-
val ElemLabels: N = "ElemLabels"
334-
val ElemTypes: N = "ElemTypes"
335333
val ExistentialTypeTree: N = "ExistentialTypeTree"
336334
val Flag : N = "Flag"
337335
val floatHash: N = "floatHash"
338336
val Ident: N = "Ident"
339337
val Import: N = "Import"
340-
val Label: N = "Label"
341338
val Literal: N = "Literal"
342339
val LiteralAnnotArg: N = "LiteralAnnotArg"
343340
val longHash: N = "longHash"
344341
val MatchCase: N = "MatchCase"
342+
val MirroredElemTypes: N = "MirroredElemTypes"
343+
val MirroredElemLabels: N = "MirroredElemLabels"
344+
val MirroredLabel: N = "MirroredLabel"
345+
val MirroredMonoType: N = "MirroredMonoType"
345346
val Modifiers: N = "Modifiers"
346-
val MonoType: N = "MonoType"
347347
val NestedAnnotArg: N = "NestedAnnotArg"
348348
val NoFlags: N = "NoFlags"
349349
val NoPrefix: N = "NoPrefix"

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

+12-8
Original file line numberDiff line numberDiff line change
@@ -323,14 +323,14 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
323323
* gets the `fromProduct` method:
324324
*
325325
* ```
326-
* def fromProduct(x$0: Product): MonoType =
326+
* def fromProduct(x$0: Product): MirroredMonoType =
327327
* new C[U](
328328
* x$0.productElement(0).asInstanceOf[U],
329329
* x$0.productElement(1).asInstanceOf[Seq[String]]: _*)
330330
* ```
331331
* where
332332
* ```
333-
* type MonoType = C[_]
333+
* type MirroredMonoType = C[_]
334334
* ```
335335
*/
336336
def fromProductBody(caseClass: Symbol, param: Tree)(implicit ctx: Context): Tree = {
@@ -362,11 +362,11 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
362362

363363
/** For an enum T:
364364
*
365-
* def ordinal(x: MonoType) = x.enumTag
365+
* def ordinal(x: MirroredMonoType) = x.enumTag
366366
*
367367
* For sealed trait with children of normalized types C_1, ..., C_n:
368368
*
369-
* def ordinal(x: MonoType) = x match {
369+
* def ordinal(x: MirroredMonoType) = x match {
370370
* case _: C_1 => 0
371371
* ...
372372
* case _: C_n => n - 1
@@ -389,9 +389,13 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
389389
}
390390

391391
/** - If `impl` is the companion of a generic sum, add `deriving.Mirror.Sum` parent
392-
* and `MonoType` and `ordinal` members.
392+
* and `MirroredMonoType` and `ordinal` members.
393393
* - If `impl` is the companion of a generic product, add `deriving.Mirror.Product` parent
394-
* and `MonoType` and `fromProduct` members.
394+
* and `MirroredMonoType` and `fromProduct` members.
395+
* - If `impl` is marked with one of the attachments ExtendsSingletonMirror, ExtendsProductMirror,
396+
* or ExtendsSumMirror, remove the attachment and generate the corresponding mirror support,
397+
* On this case the represented class or object is referred to in a pre-existing `MirroredMonoType`
398+
* member of the template.
395399
*/
396400
def addMirrorSupport(impl: Template)(implicit ctx: Context): Template = {
397401
val clazz = ctx.owner.asClass
@@ -415,11 +419,11 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
415419
}
416420
val linked = clazz.linkedClass
417421
lazy val monoType = {
418-
val existing = clazz.info.member(tpnme.MonoType).symbol
422+
val existing = clazz.info.member(tpnme.MirroredMonoType).symbol
419423
if (existing.exists && !existing.is(Deferred)) existing
420424
else {
421425
val monoType =
422-
ctx.newSymbol(clazz, tpnme.MonoType, Synthetic, TypeAlias(linked.rawTypeRef), coord = clazz.coord)
426+
ctx.newSymbol(clazz, tpnme.MirroredMonoType, Synthetic, TypeAlias(linked.rawTypeRef), coord = clazz.coord)
423427
newBody = newBody :+ TypeDef(monoType).withSpan(ctx.owner.span.focus)
424428
monoType.entered
425429
}

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

+14-14
Original file line numberDiff line numberDiff line change
@@ -815,11 +815,11 @@ trait Implicits { self: Typer =>
815815
EmptyTree
816816
}
817817

818-
/** Create an anonymous class `new Object { type MonoType = ... }`
818+
/** Create an anonymous class `new Object { type MirroredMonoType = ... }`
819819
* and mark it with given attachment so that it is made into a mirror at PostTyper.
820820
*/
821821
private def anonymousMirror(monoType: Type, attachment: Property.StickyKey[Unit], span: Span)(implicit ctx: Context) = {
822-
val monoTypeDef = untpd.TypeDef(tpnme.MonoType, untpd.TypeTree(monoType))
822+
val monoTypeDef = untpd.TypeDef(tpnme.MirroredMonoType, untpd.TypeTree(monoType))
823823
val newImpl = untpd.Template(
824824
constr = untpd.emptyConstructor,
825825
parents = untpd.TypeTree(defn.ObjectType) :: Nil,
@@ -832,14 +832,14 @@ trait Implicits { self: Typer =>
832832

833833
/** The mirror type
834834
*
835-
* <parent> { MonoType = <monoType; Label = <label> }
835+
* <parent> { MirroredMonoType = <monoType; MirroredLabel = <label> }
836836
*/
837837
private def mirrorCore(parent: Type, monoType: Type, label: Name)(implicit ctx: Context) =
838838
parent
839-
.refinedWith(tpnme.MonoType, TypeAlias(monoType))
840-
.refinedWith(tpnme.Label, TypeAlias(ConstantType(Constant(label.toString))))
839+
.refinedWith(tpnme.MirroredMonoType, TypeAlias(monoType))
840+
.refinedWith(tpnme.MirroredLabel, TypeAlias(ConstantType(Constant(label.toString))))
841841

842-
/** An implied instance for a type of the form `Mirror.Product { type MonoType = T }`
842+
/** An implied instance for a type of the form `Mirror.Product { type MirroredMonoType = T }`
843843
* where `T` is a generic product type or a case object or an enum case.
844844
*/
845845
lazy val synthesizedProductMirror: SpecialHandler =
@@ -868,8 +868,8 @@ trait Implicits { self: Typer =>
868868
val elemLabels = accessors.map(acc => ConstantType(Constant(acc.name.toString)))
869869
val mirrorType =
870870
mirrorCore(defn.Mirror_ProductType, monoType, cls.name)
871-
.refinedWith(tpnme.ElemTypes, TypeAlias(TypeOps.nestedPairs(elemTypes)))
872-
.refinedWith(tpnme.ElemLabels, TypeAlias(TypeOps.nestedPairs(elemLabels)))
871+
.refinedWith(tpnme.MirroredElemTypes, TypeAlias(TypeOps.nestedPairs(elemTypes)))
872+
.refinedWith(tpnme.MirroredElemLabels, TypeAlias(TypeOps.nestedPairs(elemLabels)))
873873
val modul = cls.linkedClass.sourceModule
874874
assert(modul.is(Module))
875875
val mirrorRef =
@@ -879,18 +879,18 @@ trait Implicits { self: Typer =>
879879
}
880880
else EmptyTree
881881
}
882-
formal.member(tpnme.MonoType).info match {
882+
formal.member(tpnme.MirroredMonoType).info match {
883883
case monoAlias @ TypeAlias(monoType) => mirrorFor(monoType)
884884
case _ => EmptyTree
885885
}
886886
}
887887

888-
/** An implied instance for a type of the form `Mirror.Sum { type MonoType = T }`
888+
/** An implied instance for a type of the form `Mirror.Sum { type MirroredMonoType = T }`
889889
* where `T` is a generic sum type.
890890
*/
891891
lazy val synthesizedSumMirror: SpecialHandler =
892892
(formal: Type, span: Span) => implicit (ctx: Context) =>
893-
formal.member(tpnme.MonoType).info match {
893+
formal.member(tpnme.MirroredMonoType).info match {
894894
case TypeAlias(monoType) if monoType.classSymbol.isGenericSum =>
895895
val cls = monoType.classSymbol
896896
val elemTypes = cls.children.map {
@@ -925,7 +925,7 @@ trait Implicits { self: Typer =>
925925
}
926926
val mirrorType =
927927
mirrorCore(defn.Mirror_SumType, monoType, cls.name)
928-
.refinedWith(tpnme.ElemTypes, TypeAlias(TypeOps.nestedPairs(elemTypes)))
928+
.refinedWith(tpnme.MirroredElemTypes, TypeAlias(TypeOps.nestedPairs(elemTypes)))
929929
val modul = cls.linkedClass.sourceModule
930930
val mirrorRef =
931931
if (modul.exists && !cls.is(Scala2x)) ref(modul).withSpan(span)
@@ -935,12 +935,12 @@ trait Implicits { self: Typer =>
935935
EmptyTree
936936
}
937937

938-
/** An implied instance for a type of the form `Mirror { type MonoType = T }`
938+
/** An implied instance for a type of the form `Mirror { type MirroredMonoType = T }`
939939
* where `T` is a generic sum or product or singleton type.
940940
*/
941941
lazy val synthesizedMirror: SpecialHandler =
942942
(formal: Type, span: Span) => implicit (ctx: Context) =>
943-
formal.member(tpnme.MonoType).info match {
943+
formal.member(tpnme.MirroredMonoType).info match {
944944
case monoAlias @ TypeAlias(monoType) =>
945945
if (monoType.termSymbol.is(CaseVal) || monoType.classSymbol.isGenericProduct)
946946
synthesizedProductMirror(formal, span)(ctx)

library/src/scala/deriving.scala

+16-16
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ object deriving {
77
sealed trait Mirror {
88

99
/** The mirrored *-type */
10-
type MonoType
10+
type MirroredMonoType
1111

1212
/** The name of the type */
13-
type Label <: String
13+
type MirroredLabel <: String
1414
}
1515

1616
object Mirror {
@@ -19,43 +19,43 @@ object deriving {
1919
trait Sum extends Mirror { self =>
2020

2121
/** The types of the alternatives */
22-
type ElemTypes <: Tuple
22+
type MirroredElemTypes <: Tuple
2323

2424
/** The ordinal number of the case class of `x`. For enums, `ordinal(x) == x.ordinal` */
25-
def ordinal(x: MonoType): Int
25+
def ordinal(x: MirroredMonoType): Int
2626
}
2727

2828
/** The Mirror for a product type */
2929
trait Product extends Mirror {
3030

3131
/** The types of the product elements */
32-
type ElemTypes <: Tuple
32+
type MirroredElemTypes <: Tuple
3333

3434
/** The names of the product elements */
35-
type ElemLabels <: Tuple
35+
type MirroredElemLabels <: Tuple
3636

3737
/** Create a new instance of type `T` with elements taken from product `p`. */
38-
def fromProduct(p: scala.Product): MonoType
38+
def fromProduct(p: scala.Product): MirroredMonoType
3939
}
4040

4141
trait Singleton extends Product {
42-
type MonoType = this.type
43-
type ElemTypes = Unit
44-
type ElemLabels = Unit
42+
type MirroredMonoType = this.type
43+
type MirroredElemTypes = Unit
44+
type MirroredElemLabels = Unit
4545
def fromProduct(p: scala.Product) = this
4646
}
4747

4848
/** A proxy for Scala 2 singletons, which do not inherit `Singleton` directly */
4949
class SingletonProxy(val value: AnyRef) extends Product {
50-
type MonoType = value.type
51-
type ElemTypes = Unit
52-
type ElemLabels = Unit
50+
type MirroredMonoType = value.type
51+
type MirroredElemTypes = Unit
52+
type MirroredElemLabels = Unit
5353
def fromProduct(p: scala.Product) = value
5454
}
5555

56-
type Of[T] = Mirror { type MonoType = T }
57-
type ProductOf[T] = Mirror.Product { type MonoType = T }
58-
type SumOf[T] = Mirror.Sum { type MonoType = T }
56+
type Of[T] = Mirror { type MirroredMonoType = T }
57+
type ProductOf[T] = Mirror.Product { type MirroredMonoType = T }
58+
type SumOf[T] = Mirror.Sum { type MirroredMonoType = T }
5959
}
6060

6161
/** Helper class to turn arrays into products */

tests/run/deriving.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ object Test extends App {
1414

1515
println(the[Mirror.ProductOf[A]].fromProduct(A(1, 2)))
1616
assert(the[Mirror.SumOf[T]].ordinal(A(1, 2)) == 0)
17-
assert(the[Mirror.Sum { type MonoType = T }].ordinal(B) == 1)
17+
assert(the[Mirror.Sum { type MirroredMonoType = T }].ordinal(B) == 1)
1818
the[Mirror.Of[A]] match {
1919
case m: Mirror.Product =>
2020
println(m.fromProduct(A(1, 2)))

tests/run/ordinal-innerclass.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ object Test extends App {
1515
val a = new A
1616
val b = new a.B
1717
val o = b.O
18-
val sum: deriving.Mirror.Sum { type MonoType = o.T }= o.T.asInstanceOf
18+
val sum: deriving.Mirror.Sum { type MirroredMonoType = o.T }= o.T.asInstanceOf
1919
assert(sum.ordinal(new o.C(1)) == 0)
2020
assert(sum.ordinal(new o.T.D()) == 1)
2121

tests/run/typeclass-derivation3.scala

+13-13
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,14 @@ object typeclasses {
4646
}
4747

4848
inline def eqlProduct[T](m: Mirror.ProductOf[T])(x: Any, y: Any): Boolean =
49-
eqlElems[m.ElemTypes](0)(x, y)
49+
eqlElems[m.MirroredElemTypes](0)(x, y)
5050

5151
inline def eqlCases[Alts](n: Int)(x: Any, y: Any, ord: Int): Boolean =
5252
inline erasedValue[Alts] match {
5353
case _: (alt *: alts1) =>
5454
if (ord == n)
5555
implicit match {
56-
case m: Mirror.ProductOf[`alt`] => eqlElems[m.ElemTypes](0)(x, y)
56+
case m: Mirror.ProductOf[`alt`] => eqlElems[m.MirroredElemTypes](0)(x, y)
5757
}
5858
else eqlCases[alts1](n + 1)(x, y, ord)
5959
case _: Unit =>
@@ -65,9 +65,9 @@ object typeclasses {
6565
inline ev match {
6666
case m: Mirror.SumOf[T] =>
6767
val ord = m.ordinal(x)
68-
ord == m.ordinal(y) && eqlCases[m.ElemTypes](0)(x, y, ord)
68+
ord == m.ordinal(y) && eqlCases[m.MirroredElemTypes](0)(x, y, ord)
6969
case m: Mirror.ProductOf[T] =>
70-
eqlElems[m.ElemTypes](0)(x, y)
70+
eqlElems[m.MirroredElemTypes](0)(x, y)
7171
}
7272
}
7373

@@ -106,7 +106,7 @@ object typeclasses {
106106
case _: (alt *: alts1) =>
107107
if (ord == n)
108108
implicit match {
109-
case m: Mirror.ProductOf[`alt`] => pickleElems[m.ElemTypes](0)(buf, x)
109+
case m: Mirror.ProductOf[`alt`] => pickleElems[m.MirroredElemTypes](0)(buf, x)
110110
}
111111
else pickleCases[alts1](n + 1)(buf, x, ord)
112112
case _: Unit =>
@@ -141,7 +141,7 @@ object typeclasses {
141141
if (ord == n)
142142
implicit match {
143143
case m: Mirror.ProductOf[`alt` & T] =>
144-
unpickleCase[`alt` & T, m.ElemTypes](buf, m)
144+
unpickleCase[`alt` & T, m.MirroredElemTypes](buf, m)
145145
}
146146
else unpickleCases[T, alts1](n + 1)(buf, ord)
147147
case _: Unit =>
@@ -154,17 +154,17 @@ object typeclasses {
154154
case m: Mirror.SumOf[T] =>
155155
val ord = m.ordinal(x)
156156
buf += ord
157-
pickleCases[m.ElemTypes](0)(buf, x, ord)
157+
pickleCases[m.MirroredElemTypes](0)(buf, x, ord)
158158
case m: Mirror.ProductOf[T] =>
159-
pickleElems[m.ElemTypes](0)(buf, x)
159+
pickleElems[m.MirroredElemTypes](0)(buf, x)
160160
}
161161
def unpickle(buf: mutable.ListBuffer[Int]): T =
162162
inline ev match {
163163
case m: Mirror.SumOf[T] =>
164164
val ord = nextInt(buf)
165-
unpickleCases[T, m.ElemTypes](0)(buf, ord)
165+
unpickleCases[T, m.MirroredElemTypes](0)(buf, ord)
166166
case m: Mirror.ProductOf[T] =>
167-
unpickleCase[T, m.ElemTypes](buf, m)
167+
unpickleCase[T, m.MirroredElemTypes](buf, m)
168168
}
169169
}
170170

@@ -201,10 +201,10 @@ object typeclasses {
201201
}
202202

203203
inline def showCase(x: Any, m: Mirror.ProductOf[_]): String = {
204-
val label = constValue[m.Label]
204+
val label = constValue[m.MirroredLabel]
205205
inline m match {
206206
case m: Mirror.Singleton => label
207-
case _ => showElems[m.ElemTypes, m.ElemLabels](0)(x).mkString(s"$label(", ", ", ")")
207+
case _ => showElems[m.MirroredElemTypes, m.MirroredElemLabels](0)(x).mkString(s"$label(", ", ", ")")
208208
}
209209
}
210210

@@ -226,7 +226,7 @@ object typeclasses {
226226
inline ev match {
227227
case m: Mirror.SumOf[T] =>
228228
val ord = m.ordinal(x)
229-
showCases[m.ElemTypes](0)(x, ord)
229+
showCases[m.MirroredElemTypes](0)(x, ord)
230230
case m: Mirror.ProductOf[T] =>
231231
showCase(x, m)
232232
}

0 commit comments

Comments
 (0)