-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add Missing parents to companions classes in stdlib-bootsrapped #17978
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -60,7 +60,7 @@ object PostTyper { | |
* mini-phase or subfunction of a macro phase equally well. But taken by themselves | ||
* they do not warrant their own group of miniphases before pickling. | ||
*/ | ||
class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase => | ||
class PostTyper extends MacroTransform with InfoTransformer { thisPhase => | ||
import tpd._ | ||
|
||
override def phaseName: String = PostTyper.name | ||
|
@@ -80,6 +80,10 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase | |
def newTransformer(using Context): Transformer = | ||
new PostTyperTransformer | ||
|
||
private var compilingScala2StdLib = false | ||
override def initContext(ctx: FreshContext): Unit = | ||
compilingScala2StdLib = ctx.settings.Yscala2Stdlib.value(using ctx) | ||
|
||
val superAcc: SuperAccessors = new SuperAccessors(thisPhase) | ||
val synthMbr: SyntheticMembers = new SyntheticMembers(thisPhase) | ||
val beanProps: BeanProperties = new BeanProperties(thisPhase) | ||
|
@@ -425,7 +429,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase | |
if sym.isOpaqueAlias then | ||
VarianceChecker.checkLambda(rhs, TypeBounds.upper(sym.opaqueAlias)) | ||
case _ => | ||
processMemberDef(super.transform(tree)) | ||
processMemberDef(super.transform(scala2LibPatch(tree))) | ||
case tree: Bind => | ||
if tree.symbol.isType && !tree.symbol.name.is(WildcardParamName) then | ||
Checking.checkGoodBounds(tree.symbol) | ||
|
@@ -534,5 +538,30 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase | |
sym.addAnnotation(Annotation(defn.ExperimentalAnnot, sym.span)) | ||
sym.companionModule.addAnnotation(Annotation(defn.ExperimentalAnnot, sym.span)) | ||
|
||
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 | ||
tree.rhs match | ||
case impl: Template => | ||
val parents1 = impl.parents :+ TypeTree(defn.SerializableType) | ||
val impl1 = cpy.Template(impl)(parents = parents1) | ||
cpy.TypeDef(tree)(rhs = impl1) | ||
else tree | ||
} | ||
|
||
protected override def infoMayChange(sym: Symbol)(using Context): Boolean = | ||
compilingScala2StdLib && sym.isAllOf(ModuleClass, butNot = Package) | ||
|
||
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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Question: Should we do that as well in Scala 3? (during desugar or Typer). I mean, if a class is Serializable should we automatically make the companion Serializable as well? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Every There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't realize Scala 2 had special logic for making the companion extend Serializable in Typer if the class itself does, I guess we could do the same for better source compatibility but otherwise it wouldn't matter. |
||
else tp | ||
case _ => tp | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,8 +9,14 @@ object TastyMiMaFilters { | |
// Probably OK: Case class with varargs | ||
ProblemMatcher.make(ProblemKind.IncompatibleTypeChange, "scala.StringContext.parts"), // before: scala.<repeated>[Predef.String]; after: scala.collection.immutable.Seq[Predef.String] @scala.annotation.internal.Repeated | ||
|
||
// Problem: Missing Serializable in companions of serializable classes | ||
ProblemMatcher.make(ProblemKind.MissingParent, "scala.*$"), | ||
// 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*$"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like these come from the fact that their companion class is a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Those where actually missing |
||
ProblemMatcher.make(ProblemKind.MissingParent, "scala.ScalaReflectionException$"), | ||
ProblemMatcher.make(ProblemKind.MissingParent, "scala.UninitializedFieldError$"), | ||
|
||
// Problem: Class[T] or ClassTag[T] with `T` equal to wildcard `_ >: Nothing <: AnyVal` instead of a specific primitive type `T` | ||
ProblemMatcher.make(ProblemKind.IncompatibleTypeChange, "scala.reflect.ManifestFactory.*.runtimeClass"), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest factoring that out ina @ThreadUnsafe lazy val