Skip to content

Commit 4c4b483

Browse files
Adapt mirror synthesis for old classes
1 parent d5f6fa2 commit 4c4b483

File tree

3 files changed

+13
-4
lines changed

3 files changed

+13
-4
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import Phases._
1919
import ast.tpd.Literal
2020

2121
import dotty.tools.dotc.transform.sjs.JSSymUtils.sjsNeedsField
22+
import dotty.tools.tasty.TastyFormat
2223

2324
import scala.annotation.tailrec
2425

@@ -107,6 +108,13 @@ object SymUtils:
107108

108109
def isGenericProduct(using Context): Boolean = whyNotGenericProduct.isEmpty
109110

111+
/** Is a case class for which mirrors support access to default arguments.
112+
*/
113+
def mirrorSupportsDefaultArguments(using Context): Boolean = self.isClass && {
114+
val d = self.asClass.classDenot
115+
TastyFormat.isVersionCompatible(28, 4, 1, d.tastyMajorVersion, d.tastyMinorVersion, d.tastyExperimentalVersion)
116+
}
117+
110118
/** Is this an old style implicit conversion?
111119
* @param directOnly only consider explicitly written methods
112120
* @param forImplicitClassOnly only consider methods generated from implicit classes

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,7 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
646646
synthesizeDef(meth, vrefss => body(cls, vrefss.head.head))
647647
}
648648
}
649-
def overrideMethod(name: TermName, info: Type, cls: Symbol, body: (Symbol, Tree) => Context ?=> Tree): Unit = { // TODO online override if changed
649+
def overrideMethod(name: TermName, info: Type, cls: Symbol, body: (Symbol, Tree) => Context ?=> Tree): Unit = {
650650
val meth = newSymbol(clazz, name, Synthetic | Method | Override, info, coord = clazz.coord)
651651
meth.enteredAfter(thisPhase)
652652
newBody = newBody :+ synthesizeExperimentalDef(meth, vrefss => body(cls, vrefss.head.head))
@@ -668,8 +668,8 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
668668
addParent(defn.Mirror_ProductClass.typeRef)
669669
addMethod(nme.fromProduct, MethodType(defn.ProductClass.typeRef :: Nil, monoType.typeRef), cls,
670670
fromProductBody(_, _, optInfo).ensureConforms(monoType.typeRef)) // t4758.scala or i3381.scala are examples where a cast is needed
671-
if cls.primaryConstructor.hasDefaultParams then overrideMethod(nme.defaultArgument,
672-
MethodType(defn.IntType :: Nil, defn.AnyType), cls, defaultArgumentBody(_, _, optInfo))
671+
if cls.mirrorSupportsDefaultArguments && cls.primaryConstructor.hasDefaultParams then overrideMethod(
672+
nme.defaultArgument, MethodType(defn.IntType :: Nil, defn.AnyType), cls, defaultArgumentBody(_, _, optInfo))
673673
}
674674
def makeSumMirror(cls: Symbol, optInfo: Option[MirrorImpl.OfSum]) = {
675675
addParent(defn.Mirror_SumClass.typeRef)

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,8 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
414414
val elemLabels = accessors.map(acc => ConstantType(Constant(acc.name.toString)))
415415
val elemsLabels = TypeOps.nestedPairs(elemLabels)
416416

417-
val elemHasDefaults = accessors.map(acc => ConstantType(Constant(acc.is(HasDefault))))
417+
val supportsDefaults = cls.mirrorSupportsDefaultArguments
418+
val elemHasDefaults = accessors.map(acc => ConstantType(Constant(supportsDefaults && acc.is(HasDefault))))
418419
val elemsHasDefaults = TypeOps.nestedPairs(elemHasDefaults)
419420

420421
val typeElems = tps.getOrElse(accessors.map(mirroredType.resultType.memberInfo(_).widenExpr))

0 commit comments

Comments
 (0)