Skip to content

Commit 9e06db7

Browse files
Add Missing parents to companions classes in stdlib-bootsrapped (#17978)
2 parents d43d6bd + 5079be7 commit 9e06db7

File tree

4 files changed

+48
-9
lines changed

4 files changed

+48
-9
lines changed

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import printing.Formatting.hl
1919
import config.Printers
2020

2121
import scala.annotation.internal.sharable
22+
import scala.annotation.threadUnsafe
2223

2324
object desugar {
2425
import untpd._
@@ -487,6 +488,7 @@ object desugar {
487488
def isNonEnumCase = !isEnumCase && (isCaseClass || isCaseObject)
488489
val isValueClass = parents.nonEmpty && isAnyVal(parents.head)
489490
// This is not watertight, but `extends AnyVal` will be replaced by `inline` later.
491+
val caseClassInScala2StdLib = isCaseClass && ctx.settings.Yscala2Stdlib.value
490492

491493
val originalTparams = constr1.leadingTypeParams
492494
val originalVparamss = asTermOnly(constr1.trailingParamss)
@@ -662,9 +664,7 @@ object desugar {
662664
// new C[...](p1, ..., pN)(moreParams)
663665
val (caseClassMeths, enumScaffolding) = {
664666
def syntheticProperty(name: TermName, tpt: Tree, rhs: Tree) =
665-
val mods =
666-
if ctx.settings.Yscala2Stdlib.value then synthetic | Inline
667-
else synthetic
667+
val mods = if caseClassInScala2StdLib then synthetic | Inline else synthetic
668668
DefDef(name, Nil, tpt, rhs).withMods(mods)
669669

670670
def productElemMeths =
@@ -782,7 +782,7 @@ object desugar {
782782
val unapplyParam = makeSyntheticParameter(tpt = classTypeRef)
783783
val unapplyRHS =
784784
if (arity == 0) Literal(Constant(true))
785-
else if ctx.settings.Yscala2Stdlib.value then scala2LibCompatUnapplyRhs(unapplyParam.name)
785+
else if caseClassInScala2StdLib then scala2LibCompatUnapplyRhs(unapplyParam.name)
786786
else Ident(unapplyParam.name)
787787
val unapplyResTp = if (arity == 0) Literal(Constant(true)) else TypeTree()
788788

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

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ object PostTyper {
6060
* mini-phase or subfunction of a macro phase equally well. But taken by themselves
6161
* they do not warrant their own group of miniphases before pickling.
6262
*/
63-
class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase =>
63+
class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
6464
import tpd._
6565

6666
override def phaseName: String = PostTyper.name
@@ -80,6 +80,10 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
8080
def newTransformer(using Context): Transformer =
8181
new PostTyperTransformer
8282

83+
private var compilingScala2StdLib = false
84+
override def initContext(ctx: FreshContext): Unit =
85+
compilingScala2StdLib = ctx.settings.Yscala2Stdlib.value(using ctx)
86+
8387
val superAcc: SuperAccessors = new SuperAccessors(thisPhase)
8488
val synthMbr: SyntheticMembers = new SyntheticMembers(thisPhase)
8589
val beanProps: BeanProperties = new BeanProperties(thisPhase)
@@ -425,7 +429,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
425429
if sym.isOpaqueAlias then
426430
VarianceChecker.checkLambda(rhs, TypeBounds.upper(sym.opaqueAlias))
427431
case _ =>
428-
processMemberDef(super.transform(tree))
432+
processMemberDef(super.transform(scala2LibPatch(tree)))
429433
case tree: Bind =>
430434
if tree.symbol.isType && !tree.symbol.name.is(WildcardParamName) then
431435
Checking.checkGoodBounds(tree.symbol)
@@ -543,5 +547,30 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
543547
sym.addAnnotation(Annotation(defn.ExperimentalAnnot, sym.span))
544548
sym.companionModule.addAnnotation(Annotation(defn.ExperimentalAnnot, sym.span))
545549

550+
private def scala2LibPatch(tree: TypeDef)(using Context) =
551+
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
557+
tree.rhs match
558+
case impl: Template =>
559+
val parents1 = impl.parents :+ TypeTree(defn.SerializableType)
560+
val impl1 = cpy.Template(impl)(parents = parents1)
561+
cpy.TypeDef(tree)(rhs = impl1)
562+
else tree
546563
}
564+
565+
protected override def infoMayChange(sym: Symbol)(using Context): Boolean =
566+
compilingScala2StdLib && sym.isAllOf(ModuleClass, butNot = Package)
567+
568+
def transformInfo(tp: Type, sym: Symbol)(using Context): Type = tp match
569+
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)
574+
else tp
575+
case _ => tp
547576
}

project/MiMaFilters.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ object MiMaFilters {
4242

4343
// Companion module class
4444
ProblemFilters.exclude[FinalClassProblem]("scala.*$"),
45-
ProblemFilters.exclude[MissingTypesProblem]("scala.*$"),
45+
46+
// Missing types {scala.runtime.AbstractFunction1}
47+
ProblemFilters.exclude[MissingTypesProblem]("scala.ScalaReflectionException$"),
48+
ProblemFilters.exclude[MissingTypesProblem]("scala.UninitializedFieldError$"),
49+
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.StringView$"),
4650

4751
// Tuples
4852
ProblemFilters.exclude[FinalClassProblem]("scala.Tuple1"),

project/TastyMiMaFilters.scala

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

12-
// Problem: Missing Serializable in companions of serializable classes
13-
ProblemMatcher.make(ProblemKind.MissingParent, "scala.*$"),
12+
// Problem: Missing type {scala.runtime.AbstractFunction1}
13+
ProblemMatcher.make(ProblemKind.MissingParent, "scala.collection.Searching.Found$"),
14+
ProblemMatcher.make(ProblemKind.MissingParent, "scala.collection.Searching.InsertionPoint$"),
15+
ProblemMatcher.make(ProblemKind.MissingParent, "scala.collection.StringView$"),
16+
ProblemMatcher.make(ProblemKind.MissingParent, "scala.jdk.FunctionWrappers.AsJava*$"),
17+
ProblemMatcher.make(ProblemKind.MissingParent, "scala.jdk.FunctionWrappers.FromJava*$"),
18+
ProblemMatcher.make(ProblemKind.MissingParent, "scala.ScalaReflectionException$"),
19+
ProblemMatcher.make(ProblemKind.MissingParent, "scala.UninitializedFieldError$"),
1420

1521
// Problem: Class[T] or ClassTag[T] with `T` equal to wildcard `_ >: Nothing <: AnyVal` instead of a specific primitive type `T`
1622
ProblemMatcher.make(ProblemKind.IncompatibleTypeChange, "scala.reflect.ManifestFactory.*.runtimeClass"),

0 commit comments

Comments
 (0)