Skip to content

Commit aac8ba7

Browse files
authored
Add missing parents to companions of case classes in stdlib-bootstrapped (#18153)
2 parents 5ca1b01 + e0070d4 commit aac8ba7

File tree

3 files changed

+38
-27
lines changed

3 files changed

+38
-27
lines changed

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

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -549,14 +549,19 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
549549

550550
private def scala2LibPatch(tree: TypeDef)(using Context) =
551551
val sym = tree.symbol
552-
if compilingScala2StdLib
553-
&& sym.is(ModuleClass) && !sym.derivesFrom(defn.SerializableClass)
554-
&& sym.companionClass.derivesFrom(defn.SerializableClass)
555-
then
556-
// Add Serializable to companion objects of serializable classes
552+
if compilingScala2StdLib && sym.is(ModuleClass) then
553+
// Add Serializable to companion objects of serializable classes,
554+
// and add AbstractFunction1 to companion objects of case classes with 1 parameter.
557555
tree.rhs match
558556
case impl: Template =>
559-
val parents1 = impl.parents :+ TypeTree(defn.SerializableType)
557+
var parents1 = impl.parents
558+
val companionClass = sym.companionClass
559+
if !sym.derivesFrom(defn.SerializableClass) && companionClass.derivesFrom(defn.SerializableClass) then
560+
parents1 = parents1 :+ TypeTree(defn.SerializableType)
561+
argTypeOfCaseClassThatNeedsAbstractFunction1(sym) match
562+
case Some(args) if parents1.head.symbol.owner == defn.ObjectClass =>
563+
parents1 = New(defn.AbstractFunctionClass(1).typeRef).select(nme.CONSTRUCTOR).appliedToTypes(args).ensureApplied :: parents1.tail
564+
case _ =>
560565
val impl1 = cpy.Template(impl)(parents = parents1)
561566
cpy.TypeDef(tree)(rhs = impl1)
562567
else tree
@@ -567,10 +572,31 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
567572

568573
def transformInfo(tp: Type, sym: Symbol)(using Context): Type = tp match
569574
case info: ClassInfo =>
570-
if !sym.derivesFrom(defn.SerializableClass)
571-
&& sym.companionClass.derivesFrom(defn.SerializableClass)
572-
then
573-
info.derivedClassInfo(declaredParents = info.parents :+ defn.SerializableType)
575+
var parents1 = info.parents
576+
val companionClass = sym.companionClass
577+
if !sym.derivesFrom(defn.SerializableClass) && companionClass.derivesFrom(defn.SerializableClass) then
578+
parents1 = parents1 :+ defn.SerializableType
579+
argTypeOfCaseClassThatNeedsAbstractFunction1(sym) match
580+
case Some(args) if parents1.head.typeSymbol == defn.ObjectClass =>
581+
parents1 = defn.AbstractFunctionClass(1).typeRef.appliedTo(args) :: parents1.tail
582+
case _ =>
583+
if parents1 ne info.parents then info.derivedClassInfo(declaredParents = parents1)
574584
else tp
575585
case _ => tp
586+
587+
private def argTypeOfCaseClassThatNeedsAbstractFunction1(sym: Symbol)(using Context): Option[List[Type]] =
588+
val companionClass = sym.companionClass
589+
if companionClass.is(CaseClass)
590+
&& !companionClass.primaryConstructor.is(Private)
591+
&& !companionClass.primaryConstructor.info.isVarArgsMethod
592+
then
593+
sym.info.decl(nme.apply).info match
594+
case info: MethodType =>
595+
info.paramInfos match
596+
case arg :: Nil =>
597+
Some(arg :: info.resultType :: Nil)
598+
case args => None
599+
case _ => None
600+
else
601+
None
576602
}

project/MiMaFilters.scala

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,6 @@ object MiMaFilters {
6666
// Companion module class
6767
ProblemFilters.exclude[FinalClassProblem]("scala.*$"),
6868

69-
// Missing types {scala.runtime.AbstractFunction1}
70-
ProblemFilters.exclude[MissingTypesProblem]("scala.ScalaReflectionException$"),
71-
ProblemFilters.exclude[MissingTypesProblem]("scala.UninitializedFieldError$"),
72-
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.StringView$"),
73-
7469
// Scala 2 intrinsic macros
7570
ProblemFilters.exclude[FinalMethodProblem]("scala.StringContext.s"),
7671

@@ -131,15 +126,12 @@ object MiMaFilters {
131126
"scala.collection.mutable.LinkedHashMap.newBuilder", "scala.collection.mutable.LinkedHashSet.newBuilder",
132127
"scala.collection.mutable.LongMap#ToBuildFrom.newBuilder",
133128
"scala.collection.mutable.PriorityQueue#ResizableArrayAccess.this",
134-
"scala.collection.StringView.andThen", "scala.collection.StringView.compose",
135129
"scala.concurrent.BatchingExecutor#AbstractBatch.this",
136130
"scala.concurrent.Channel#LinkedList.this",
137131
"scala.Enumeration#ValueOrdering.this",
138132
"scala.io.Source#RelaxedPosition.this",
139133
"scala.PartialFunction#OrElse.andThen", "scala.PartialFunction#OrElse.orElse",
140134
"scala.runtime.Rich*.num", "scala.runtime.Rich*.ord",
141-
"scala.ScalaReflectionException.andThen", "scala.ScalaReflectionException.compose",
142-
"scala.UninitializedFieldError.andThen", "scala.UninitializedFieldError.compose",
143135
"scala.util.Properties.<clinit>",
144136
"scala.util.Sorting.scala$util$Sorting$$mergeSort$default$5",
145137
).map(ProblemFilters.exclude[DirectMissingMethodProblem])
@@ -216,6 +208,8 @@ object MiMaFilters {
216208
"scala.collection.mutable.RedBlackTree#Node.apply", "scala.collection.mutable.RedBlackTree#Node.leaf", "scala.collection.mutable.RedBlackTree#Node.unapply", "scala.collection.mutable.RedBlackTree#Tree.empty",
217209
"scala.collection.mutable.UnrolledBuffer.unrolledlength", "scala.collection.mutable.UnrolledBuffer#Unrolled.<init>$default$4",
218210
"scala.collection.Searching#Found.apply", "scala.collection.Searching#Found.unapply",
211+
"scala.collection.Searching#Found.andThen", "scala.collection.Searching#Found.compose",
212+
"scala.collection.Searching#InsertionPoint.andThen", "scala.collection.Searching#InsertionPoint.compose",
219213
"scala.collection.Searching#InsertionPoint.apply", "scala.collection.Searching#InsertionPoint.unapply",
220214
"scala.collection.SortedMapFactoryDefaults.empty", "scala.collection.SortedMapFactoryDefaults.fromSpecific",
221215
"scala.collection.SortedMapOps.ordMsg", "scala.collection.SortedSetOps.ordMsg",

project/TastyMiMaFilters.scala

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,6 @@ object TastyMiMaFilters {
4444
// Probably OK: Case class with varargs
4545
ProblemMatcher.make(ProblemKind.IncompatibleTypeChange, "scala.StringContext.parts"), // before: scala.<repeated>[Predef.String]; after: scala.collection.immutable.Seq[Predef.String] @scala.annotation.internal.Repeated
4646

47-
// Problem: Missing type {scala.runtime.AbstractFunction1}
48-
ProblemMatcher.make(ProblemKind.MissingParent, "scala.collection.Searching.Found$"),
49-
ProblemMatcher.make(ProblemKind.MissingParent, "scala.collection.Searching.InsertionPoint$"),
50-
ProblemMatcher.make(ProblemKind.MissingParent, "scala.collection.StringView$"),
51-
ProblemMatcher.make(ProblemKind.MissingParent, "scala.jdk.FunctionWrappers.AsJava*$"),
52-
ProblemMatcher.make(ProblemKind.MissingParent, "scala.jdk.FunctionWrappers.FromJava*$"),
53-
ProblemMatcher.make(ProblemKind.MissingParent, "scala.ScalaReflectionException$"),
54-
ProblemMatcher.make(ProblemKind.MissingParent, "scala.UninitializedFieldError$"),
55-
5647
// Probably OK: ConstantType for `null` versus `scala.Null`
5748
// Calls to the default getter seem to link correctly.
5849
// Tested in stdlib-bootstrapped/test/scala/collection/UnrolledBufferTest.scala

0 commit comments

Comments
 (0)