Skip to content

Fix #2944: propagate information from GADT bounds to normal info. #2958

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 5 commits into from
Sep 21, 2017

Conversation

DarkDimius
Copy link
Contributor

This allows all other parts of pipeline to be less aware of existence
of the GADT bounds.

In particular, it makes us pickle them as normal type bounds.

@DarkDimius
Copy link
Contributor Author

All tests passed!
@nicolasstucki, could you please check if it fixes the original test-case?
@odersky please review the code.

@DarkDimius
Copy link
Contributor Author

@nicolasstucki, i've added a test file for #2944 but it just tests compilation, which produced wrong tasty before this fix.

def get(k: K): K = k
def foo: K = {
this match {
case that: Map2[b] => that.get(3.asInstanceOf[b])
Copy link
Contributor

Choose a reason for hiding this comment

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

This test case passes my the check with my tests 👍

Copy link
Member

Choose a reason for hiding this comment

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

Do we have a real test for this now?

def foo: K = {
this match {
case that: Map2[b] => that.get(3.asInstanceOf[b])
//case that: Map2[c] => that.get(4.asInstanceOf[K])
Copy link
Contributor

@nicolasstucki nicolasstucki Aug 4, 2017

Choose a reason for hiding this comment

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

This one still crashes while trying to type that.get(4.asInstanceOf[K].asInstanceOf[b @ b]).


import tpd._

def transformSym(sym: SymDenotation)(implicit ctx: Context): SymDenotation = {
if (sym.is(BindDefinedType) && ctx.gadt.bounds.contains(sym.symbol)) {
sym.copySymDenotation(info = ctx.gadt.bounds.apply(sym.symbol) & sym.info)
Copy link
Member

Choose a reason for hiding this comment

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

you could probably remove sym.symbol from the ctx.gadt.bounds map at that point too.

Copy link
Member

Choose a reason for hiding this comment

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

I still think this is possible but ¯\_(ツ)_/¯


import tpd._

def transformSym(sym: SymDenotation)(implicit ctx: Context): SymDenotation = {
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick: sym is usually used for symbols, for a denotation I would use ref or d.

@DarkDimius
Copy link
Contributor Author

DarkDimius commented Aug 4, 2017 via email

@DarkDimius
Copy link
Contributor Author

DarkDimius commented Aug 4, 2017 via email

@smarter
Copy link
Member

smarter commented Aug 4, 2017

Name sym is used consistently in all SymTransforms. See original trait.

% git grep "def transformSym" compiler
compiler/src/dotty/tools/dotc/core/DenotTransformers.scala:    def transformSym(sym: SymDenotation)(implicit ctx: Context): SymDenotation
compiler/src/dotty/tools/dotc/transform/Flatten.scala:  def transformSym(ref: SymDenotation)(implicit ctx: Context) = {
compiler/src/dotty/tools/dotc/transform/Getters.scala:  override def transformSym(d: SymDenotation)(implicit ctx: Context): SymDenotation = {
compiler/src/dotty/tools/dotc/transform/Mixin.scala:  override def transformSym(sym: SymDenotation)(implicit ctx: Context): SymDenotation =
compiler/src/dotty/tools/dotc/transform/MoveStatics.scala:  def transformSym(sym: SymDenotation)(implicit ctx: Context): SymDenotation = {
compiler/src/dotty/tools/dotc/transform/NormalizeFlags.scala:  def transformSym(ref: SymDenotation)(implicit ctx: Context) = {
compiler/src/dotty/tools/dotc/transform/PrivateToStatic.scala.disabled:  override def transformSym(sd: SymDenotation)(implicit ctx: Context): SymDenotation =
compiler/src/dotty/tools/dotc/transform/TreeChecker.scala:  def transformSym(symd: SymDenotation)(implicit ctx: Context): SymDenotation = {

I think everyone is confused about what name to use :).

@DarkDimius
Copy link
Contributor Author

This one still crashes while trying to type that.get(4.asInstanceOf[K].asInstanceOf[b @ b]).

Nice) will look into it! Curious why the bind node is inside of cast...

@smarter
Copy link
Member

smarter commented Aug 4, 2017

You can't. You'll need to remove it from top context

Why? When we create a fresh context we keep a reference to the same GADTMap in _gadt.

@nicolasstucki nicolasstucki mentioned this pull request Aug 4, 2017
@DarkDimius
Copy link
Contributor Author

This one still crashes while trying to type that.get(4.asInstanceOf[K].asInstanceOf[b @ b]).

@nicolasstucki , though I authored this testcase, I forgot how to make this bind appear.
The tasty looks correct. The error happens on reading. How did you force reading it?

@DarkDimius
Copy link
Contributor Author

Ok, found a bug by reading code. TreeUnpickeler.readTpt is obviously wrong.

@nicolasstucki
Copy link
Contributor

@DarkDimius you can reproduce it easily for this branch https://github.com/dotty-staging/dotty/tree/link-from-tasty-show-bug. Just run the reproducefailure.sh script.

@nicolasstucki
Copy link
Contributor

That branch contains the current fix.

@DarkDimius
Copy link
Contributor Author

@nicolasstucki, could you please validate that the last commit fixes the issue?

@nicolasstucki
Copy link
Contributor

It did not fix it, but that is clearly the source of the issue. Now I get:

exception while typing c of class class dotty.tools.dotc.ast.Trees$Ident # 401946
exception while typing 4.asInstanceOf[K].asInstanceOf[c] of class class dotty.tools.dotc.ast.Trees$TypeApply # 401947
exception while typing that.get(4.asInstanceOf[K].asInstanceOf[c]) of class class dotty.tools.dotc.ast.Trees$Apply # 402179

Note that you did replace the binding by the Ident but it still can't pas Ycheck.

@DarkDimius
Copy link
Contributor Author

DarkDimius commented Aug 4, 2017

@nicolasstucki, sorry. I did a stupid mistake :-) Fix incomming.

@DarkDimius
Copy link
Contributor Author

Oh... it is actually much worse: on unpickling, c becomes a term.

@DarkDimius
Copy link
Contributor Author

aaaand we create symbol for it twice on unpickling. And those two symbols are obviously incompatible between each other.

@DarkDimius
Copy link
Contributor Author

I propose we postpone fixing the remaining bug till next dotty meeting. My proposed fix is to revert 79e2228 and ad6b578. Those commits made bind be handled as-if it was TypeTree in Tasty. This broke a lot of stuff because unpickler assumes that it can read TypeTrees repeatedly, which is not true for bind, which is a DefTree. We assume in multiple locations that DefTree should be only read once, as you'll get a fresh symbol every time you read it.

@DarkDimius
Copy link
Contributor Author

@nicolasstucki, is the remaining bug also a blocker?

@nicolasstucki
Copy link
Contributor

nicolasstucki commented Aug 4, 2017

@DarkDimius ~~~the fix in the first commit unblocked it~~~. The second could be left for later, lets open a separate issue for it. Thanks.

@nicolasstucki
Copy link
Contributor

Unfortunately the the first fix did not work in the original code from strawman.collection.Map.equals.

I minimised the issue again to

trait Map2[K] {
  def get(k: K): K = k
  def foo = {
    val o = new Object 
    o match { // now match on Object and not this
      case that: Map2[b] => that.get(3.asInstanceOf[b])
      case _ => get(5.asInstanceOf[K])
    }
  }
}

@DarkDimius
Copy link
Contributor Author

@nicolasstucki and I have figured that this is another manifestation of #2958 (comment)

This allows all other parts of pipeline to be less aware of existence
of the GADT bounds.

In particular, it makes us pickle them as normal type bounds.
DarkDimius and others added 4 commits September 21, 2017 09:54
binds are "shared" as type trees would be shared,
see scala#2510

But they are not type trees, as you can't have them inside TypeApply.
See i2944a.scala.
@nicolasstucki
Copy link
Contributor

Rebased.

@smarter could you re-review this quickly before merging.

@nicolasstucki nicolasstucki merged commit 0802abd into scala:master Sep 21, 2017
@liufengyun
Copy link
Contributor

test performance please

This PR fails the compilation of https://github.com/liufengyun/scalaPB on the bench server.

@dottybot
Copy link
Member

performance test scheduled: 1 job(s) in queue, 0 running.

@dottybot
Copy link
Member

performance test failed:

[check /data/workspace/bench/logs/pull-2958-09-25-14.39.out for more information]

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.

5 participants