From e0070d4ece3885b19b18ee863ff8a0d959191379 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 28 Jun 2023 16:02:20 +0200 Subject: [PATCH] Add missing parents to companions of case classes in stdlib-bootsrapped --- .../tools/dotc/transform/PostTyper.scala | 46 +++++++++++++++---- project/MiMaFilters.scala | 10 +--- project/TastyMiMaFilters.scala | 9 ---- 3 files changed, 38 insertions(+), 27 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala index b2294564dc1d..ae77439927f7 100644 --- a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala +++ b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala @@ -549,14 +549,19 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase => private def scala2LibPatch(tree: TypeDef)(using Context) = val sym = tree.symbol - if compilingScala2StdLib - && sym.is(ModuleClass) && !sym.derivesFrom(defn.SerializableClass) - && sym.companionClass.derivesFrom(defn.SerializableClass) - then - // Add Serializable to companion objects of serializable classes + if compilingScala2StdLib && sym.is(ModuleClass) then + // Add Serializable to companion objects of serializable classes, + // and add AbstractFunction1 to companion objects of case classes with 1 parameter. tree.rhs match case impl: Template => - val parents1 = impl.parents :+ TypeTree(defn.SerializableType) + var parents1 = impl.parents + val companionClass = sym.companionClass + if !sym.derivesFrom(defn.SerializableClass) && companionClass.derivesFrom(defn.SerializableClass) then + parents1 = parents1 :+ TypeTree(defn.SerializableType) + argTypeOfCaseClassThatNeedsAbstractFunction1(sym) match + case Some(args) if parents1.head.symbol.owner == defn.ObjectClass => + parents1 = New(defn.AbstractFunctionClass(1).typeRef).select(nme.CONSTRUCTOR).appliedToTypes(args).ensureApplied :: parents1.tail + case _ => val impl1 = cpy.Template(impl)(parents = parents1) cpy.TypeDef(tree)(rhs = impl1) else tree @@ -567,10 +572,31 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase => def transformInfo(tp: Type, sym: Symbol)(using Context): Type = tp match case info: ClassInfo => - if !sym.derivesFrom(defn.SerializableClass) - && sym.companionClass.derivesFrom(defn.SerializableClass) - then - info.derivedClassInfo(declaredParents = info.parents :+ defn.SerializableType) + var parents1 = info.parents + val companionClass = sym.companionClass + if !sym.derivesFrom(defn.SerializableClass) && companionClass.derivesFrom(defn.SerializableClass) then + parents1 = parents1 :+ defn.SerializableType + argTypeOfCaseClassThatNeedsAbstractFunction1(sym) match + case Some(args) if parents1.head.typeSymbol == defn.ObjectClass => + parents1 = defn.AbstractFunctionClass(1).typeRef.appliedTo(args) :: parents1.tail + case _ => + if parents1 ne info.parents then info.derivedClassInfo(declaredParents = parents1) else tp case _ => tp + + private def argTypeOfCaseClassThatNeedsAbstractFunction1(sym: Symbol)(using Context): Option[List[Type]] = + val companionClass = sym.companionClass + if companionClass.is(CaseClass) + && !companionClass.primaryConstructor.is(Private) + && !companionClass.primaryConstructor.info.isVarArgsMethod + then + sym.info.decl(nme.apply).info match + case info: MethodType => + info.paramInfos match + case arg :: Nil => + Some(arg :: info.resultType :: Nil) + case args => None + case _ => None + else + None } diff --git a/project/MiMaFilters.scala b/project/MiMaFilters.scala index 98dbf4859d92..f39cb3351b04 100644 --- a/project/MiMaFilters.scala +++ b/project/MiMaFilters.scala @@ -66,11 +66,6 @@ object MiMaFilters { // Companion module class ProblemFilters.exclude[FinalClassProblem]("scala.*$"), - // Missing types {scala.runtime.AbstractFunction1} - ProblemFilters.exclude[MissingTypesProblem]("scala.ScalaReflectionException$"), - ProblemFilters.exclude[MissingTypesProblem]("scala.UninitializedFieldError$"), - ProblemFilters.exclude[MissingTypesProblem]("scala.collection.StringView$"), - // Scala 2 intrinsic macros ProblemFilters.exclude[FinalMethodProblem]("scala.StringContext.s"), @@ -131,15 +126,12 @@ object MiMaFilters { "scala.collection.mutable.LinkedHashMap.newBuilder", "scala.collection.mutable.LinkedHashSet.newBuilder", "scala.collection.mutable.LongMap#ToBuildFrom.newBuilder", "scala.collection.mutable.PriorityQueue#ResizableArrayAccess.this", - "scala.collection.StringView.andThen", "scala.collection.StringView.compose", "scala.concurrent.BatchingExecutor#AbstractBatch.this", "scala.concurrent.Channel#LinkedList.this", "scala.Enumeration#ValueOrdering.this", "scala.io.Source#RelaxedPosition.this", "scala.PartialFunction#OrElse.andThen", "scala.PartialFunction#OrElse.orElse", "scala.runtime.Rich*.num", "scala.runtime.Rich*.ord", - "scala.ScalaReflectionException.andThen", "scala.ScalaReflectionException.compose", - "scala.UninitializedFieldError.andThen", "scala.UninitializedFieldError.compose", "scala.util.Properties.", "scala.util.Sorting.scala$util$Sorting$$mergeSort$default$5", ).map(ProblemFilters.exclude[DirectMissingMethodProblem]) @@ -216,6 +208,8 @@ object MiMaFilters { "scala.collection.mutable.RedBlackTree#Node.apply", "scala.collection.mutable.RedBlackTree#Node.leaf", "scala.collection.mutable.RedBlackTree#Node.unapply", "scala.collection.mutable.RedBlackTree#Tree.empty", "scala.collection.mutable.UnrolledBuffer.unrolledlength", "scala.collection.mutable.UnrolledBuffer#Unrolled.$default$4", "scala.collection.Searching#Found.apply", "scala.collection.Searching#Found.unapply", + "scala.collection.Searching#Found.andThen", "scala.collection.Searching#Found.compose", + "scala.collection.Searching#InsertionPoint.andThen", "scala.collection.Searching#InsertionPoint.compose", "scala.collection.Searching#InsertionPoint.apply", "scala.collection.Searching#InsertionPoint.unapply", "scala.collection.SortedMapFactoryDefaults.empty", "scala.collection.SortedMapFactoryDefaults.fromSpecific", "scala.collection.SortedMapOps.ordMsg", "scala.collection.SortedSetOps.ordMsg", diff --git a/project/TastyMiMaFilters.scala b/project/TastyMiMaFilters.scala index f2c17701643d..3d2aea53426d 100644 --- a/project/TastyMiMaFilters.scala +++ b/project/TastyMiMaFilters.scala @@ -44,15 +44,6 @@ object TastyMiMaFilters { // Probably OK: Case class with varargs ProblemMatcher.make(ProblemKind.IncompatibleTypeChange, "scala.StringContext.parts"), // before: scala.[Predef.String]; after: scala.collection.immutable.Seq[Predef.String] @scala.annotation.internal.Repeated - // Problem: Missing type {scala.runtime.AbstractFunction1} - ProblemMatcher.make(ProblemKind.MissingParent, "scala.collection.Searching.Found$"), - ProblemMatcher.make(ProblemKind.MissingParent, "scala.collection.Searching.InsertionPoint$"), - ProblemMatcher.make(ProblemKind.MissingParent, "scala.collection.StringView$"), - ProblemMatcher.make(ProblemKind.MissingParent, "scala.jdk.FunctionWrappers.AsJava*$"), - ProblemMatcher.make(ProblemKind.MissingParent, "scala.jdk.FunctionWrappers.FromJava*$"), - ProblemMatcher.make(ProblemKind.MissingParent, "scala.ScalaReflectionException$"), - ProblemMatcher.make(ProblemKind.MissingParent, "scala.UninitializedFieldError$"), - // Probably OK: ConstantType for `null` versus `scala.Null` // Calls to the default getter seem to link correctly. // Tested in stdlib-bootstrapped/test/scala/collection/UnrolledBufferTest.scala