Skip to content

Fix -Ytest-pickler with super trees #5516

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

Merged
merged 1 commit into from
Oct 15, 2022

Conversation

smarter
Copy link
Member

@smarter smarter commented Nov 25, 2018

in t247.scala, super[Tree] was typed as SuperType(TreeMap, Tree) but
the unpickled type was reconstructed as SuperType(TreeMap, Tree[KEY, Entry]) leading to a -Ytest-pickler failure. We fix this by tweaking
TypeAssigner for Super, and while we're at it we also add some checks
related to Super in TreeChecker.

@@ -329,7 +329,7 @@ trait TypeAssigner {
errorType("ambiguous parent class qualifier", tree.pos)
}
val owntype =
if (mixinClass.exists) mixinClass.appliedRef
if (mixinClass.exists) mixinClass.typeRef
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think neither old nor new version is right. What about this scenario?

trait A[X]
class B extends A[Int] {
  super[A] // should have type A[Int], not A, or A[X]
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's a bit weird, but if we change this then we need to change the pickling/unpickling scheme for super which currently does:

            case SUPER =>
              val qual = readTerm()
              val (mixId, mixTpe) = ifBefore(end)(readQualId(), (untpd.EmptyTypeIdent, NoType))
tpd.Super(qual, mixId, ctx.mode.is(Mode.InSuperCall), mixTpe.typeSymbol

So won't work with mix being an AppliedType.

Alternatively we could change SuperType#underyling to work like SuperType#superType, currently they're different:

  abstract case class SuperType(thistpe: Type, supertpe: Type) extends CachedProxyType with SingletonType {
    override def underlying(implicit ctx: Context): Type = supertpe
    override def superType(implicit ctx: Context): Type =
thistpe.baseType(supertpe.typeSymbol)

But note that in practice I haven't found a case where the current definition breaks something, e.g. in findMember we call underlying on SuperType but that ends up working out since findMember keeps around the prefix of the call as pre which contains all the information we need to figure out the type parameters.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe underlying in supertype is fine.

I don't see right now why pickler/unpickler has to change. Should we not instead change the TypeAssigner to do the same as SuperType$superType?

Copy link
Member Author

@smarter smarter Mar 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coming back to this PR 2 years (!) later, I believe I'm still confused by why underlying and superType are different in SuperType, if I follow your advice of making TypeAssigner use the same logic as superType to set superTpe, then they would always be the same anyway. Would you mind taking another look at this?

Copy link
Contributor

@odersky odersky Oct 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have deep insights here either. underlying does not do baseType invocations, and superType should probably do that.

That said, I now think the change in TypeAssigner makes sense. If everything passes with that change, let's do it.

@odersky odersky assigned smarter and unassigned odersky Dec 3, 2018
@smarter smarter assigned odersky and unassigned smarter Mar 23, 2021
@anatoliykmetyuk
Copy link
Contributor

There was no activity on this one for a long while, so let's close it.

@smarter
Copy link
Member Author

smarter commented Jul 27, 2021

I disagree, I asked a question on March 23.

@smarter smarter reopened this Jul 27, 2021
@anatoliykmetyuk
Copy link
Contributor

/cc @odersky

@odersky odersky removed their assignment Oct 15, 2022
@smarter smarter force-pushed the fix-pickling-super branch from 08a8fe7 to acb9519 Compare October 15, 2022 13:08
in t247.scala, `super[Tree]` was typed as `SuperType(TreeMap, Tree)` but
the unpickled type was reconstructed as `SuperType(TreeMap, Tree[KEY,
Entry])` leading to a -Ytest-pickler failure. We fix this by tweaking
TypeAssigner for Super, and while we're at it we also add some checks
related to Super in TreeChecker.
@smarter smarter force-pushed the fix-pickling-super branch from acb9519 to 1e00117 Compare October 15, 2022 13:08
@smarter smarter enabled auto-merge October 15, 2022 13:09
@smarter smarter merged commit 7a0165b into scala:main Oct 15, 2022
@smarter smarter deleted the fix-pickling-super branch October 15, 2022 14:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants