Skip to content

Commit f5a7f6b

Browse files
Remove ProductN parent on case classes
This means the compiler needs to systematically synthesise productElement and productArity, which aligns with what scalac is doing. This change gets rid of last reference to scala.ProductN! 🎉
1 parent 8815b40 commit f5a7f6b

File tree

3 files changed

+10
-24
lines changed

3 files changed

+10
-24
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,8 @@ object desugar {
291291
case _ => false
292292
}
293293

294-
val isCaseClass = mods.is(Case) && !mods.is(Module)
294+
val isCaseClass = mods.is(Case) && !mods.is(Module)
295+
val isCaseObject = mods.is(Case) && mods.is(Module)
295296
val isEnum = mods.hasMod[Mod.Enum]
296297
val isEnumCase = isLegalEnumCase(cdef)
297298
val isValueClass = parents.nonEmpty && isAnyVal(parents.head)
@@ -360,7 +361,7 @@ object desugar {
360361
// pN: TN = pN: @uncheckedVariance)(moreParams) =
361362
// new C[...](p1, ..., pN)(moreParams)
362363
//
363-
// Above arity 22 we also synthesize:
364+
// To add to both case classes and objects
364365
// def productArity = N
365366
// def productElement(i: Int): Any = i match { ... }
366367
//
@@ -414,33 +415,21 @@ object desugar {
414415
}
415416
}
416417

417-
// Above MaxTupleArity we extend Product instead of ProductN, in this
418-
// case we need to synthesise productElement & productArity.
419-
def largeProductMeths =
420-
if (arity > Definitions.MaxTupleArity) productElement :: productArity :: Nil
421-
else Nil
422-
423418
if (isCaseClass)
424-
largeProductMeths ::: copyMeths ::: enumTagMeths ::: productElemMeths.toList
419+
productElement :: productArity :: copyMeths ::: enumTagMeths ::: productElemMeths.toList
420+
else if (isCaseObject)
421+
productArity :: productElement :: Nil
425422
else Nil
426423
}
427424

428425
def anyRef = ref(defn.AnyRefAlias.typeRef)
429-
def productConstr(n: Int) = {
430-
val tycon = scalaDot((str.Product + n).toTypeName)
431-
val targs = constrVparamss.head map (_.tpt)
432-
if (targs.isEmpty) tycon else AppliedTypeTree(tycon, targs)
433-
}
434-
def product =
435-
if (arity > Definitions.MaxTupleArity) scalaDot(str.Product.toTypeName)
436-
else productConstr(arity)
437426

438-
// Case classes and case objects get Product/ProductN parents
427+
// Case classes and case objects get Product parents
439428
var parents1 = parents
440429
if (isEnumCase && parents.isEmpty)
441430
parents1 = enumClassTypeRef :: Nil
442-
if (mods.is(Case))
443-
parents1 = parents1 :+ product // TODO: This also adds Product0 to case objects. Do we want that?
431+
if (isCaseClass | isCaseObject)
432+
parents1 = parents1 :+ scalaDot(str.Product.toTypeName)
444433
if (isEnum)
445434
parents1 = parents1 :+ ref(defn.EnumType)
446435

@@ -499,7 +488,6 @@ object desugar {
499488
companionDefs(anyRef, Nil)
500489
else Nil
501490

502-
503491
// For an implicit class C[Ts](p11: T11, ..., p1N: T1N) ... (pM1: TM1, .., pMN: TMN), the method
504492
// synthetic implicit C[Ts](p11: T11, ..., p1N: T1N) ... (pM1: TM1, ..., pMN: TMN): C[Ts] =
505493
// new C[Ts](p11, ..., p1N) ... (pM1, ..., pMN) =

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,6 @@ class Definitions {
700700
def FunctionClassPerRun = new PerRun[Array[Symbol]](implicit ctx => ImplementedFunctionType.map(_.symbol.asClass))
701701

702702
lazy val TupleType = mkArityArray("scala.Tuple", MaxTupleArity, 2)
703-
lazy val ProductNType = mkArityArray("scala.Product", MaxTupleArity, 0)
704703

705704
def FunctionClass(n: Int, isImplicit: Boolean = false)(implicit ctx: Context) =
706705
if (isImplicit) ctx.requiredClass("scala.ImplicitFunction" + n.toString)
@@ -715,7 +714,6 @@ class Definitions {
715714
else FunctionClass(n, isImplicit).typeRef
716715

717716
private lazy val TupleTypes: Set[TypeRef] = TupleType.toSet
718-
private lazy val ProductTypes: Set[TypeRef] = ProductNType.toSet
719717

720718
/** If `cls` is a class in the scala package, its name, otherwise EmptyTypeName */
721719
def scalaClassName(cls: Symbol)(implicit ctx: Context): TypeName =

tests/neg/t1843-variances.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
object Crash {
88
trait UpdateType[A]
9-
case class StateUpdate[+A](updateType : UpdateType[A], value : A) // error
9+
case class StateUpdate[+A](updateType : UpdateType[A], value : A) // error // error
1010
case object IntegerUpdateType extends UpdateType[Integer]
1111

1212
//However this method will cause a crash

0 commit comments

Comments
 (0)