Skip to content
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

Saving symbol lookup from typedIdent. #1521

Merged
merged 9 commits into from Nov 1, 2012
Merged

Saving symbol lookup from typedIdent. #1521

merged 9 commits into from Nov 1, 2012

Conversation

paulp
Copy link
Contributor

@paulp paulp commented Oct 23, 2012

Anticipating the appeals to performance, I offer this coarse measurement. My times are the good ones. Better measurements are welcome, but I convinced myself at least that I wasn't hurting anything.

% for i in 1 2 3; do time scalac3 -J-Xmx1g -d $(mktemp -dt foo) $(find /scratch/trunk5/src/library/scala/collection/mutable -name '*.scala') ; done
28.139 real, 68.872 user, 1.186 sys
30.963 real, 70.071 user, 1.260 sys
29.741 real, 73.389 user, 1.249 sys
% for i in 1 2 3; do time ./pack-whats-in-a-name/bin/scalac -J-Xmx1g -d $(mktemp -dt foo) $(find /scratch/trunk5/src/library/scala/collection/mutable -name '*.scala') ; done
28.129 real, 68.396 user, 1.176 sys
27.571 real, 67.318 user, 1.081 sys
27.240 real, 66.336 user, 1.046 sys

Review by @odersky, @adriaanm.

Too many unrelated things are intermingled.  If you
want to know what symbol corresponds to a particular name
in a particular context, you shouldn't have to involve
either a Tree or a Typer to find that out.  I toiled line
by line over typedIdent until it had shed its redundancies
and freed itself from the bowels of typed1.

The mechanism of name lookup is such that adding a
qualifier when the occasion calls for it is inseperable
without a lot more effort.  So to preserve a sane interface
I devised this small partitioning of outcomes.

  case class LookupSucceeded(qualifier, symbol)
  case class LookupAmbiguous(msg)
  case class LookupInaccessible(symbol, msg)
  case class LookupNotFound(msg)
This unifies several disparate/ad-hoc mechanisms for
excluding symbols from eligibility in a single predicate.
This is the method on Context:

  def lookupSymbol(name: Name, qualifies: Symbol => Boolean)

The logic is largely that which was buried in typedIdent,
except that I fixed SI-3160 so that import foo._ does not
inject foo's private members into your namespace.
Given that it's just a reimplementation of Option, we may as
well not also reimplement methods like map and getOrElse at
every call site.
Greasing the wheels for Typer's well-being.
Apply convenience methods to strip away complications.
This completes the transition.  Typer's bevy of special
cases to influence symbol lookup are encoded in its local
"qualifies" method, which it passes to lookupSymbol.
This allows access to be done correctly without infecting
Typer with such pedestrian concerns.
@scala-jenkins
Copy link

Started jenkins job pr-rangepos at https://scala-webapps.epfl.ch/jenkins/job/pr-rangepos/770/

@scala-jenkins
Copy link

Started jenkins job pr-scala-testsuite-linux-opt at https://scala-webapps.epfl.ch/jenkins/job/pr-scala-testsuite-linux-opt/1481/

@scala-jenkins
Copy link

jenkins job pr-scala-testsuite-linux-opt: Success - https://scala-webapps.epfl.ch/jenkins/job/pr-scala-testsuite-linux-opt/1481/

@scala-jenkins
Copy link

jenkins job pr-rangepos: Success - https://scala-webapps.epfl.ch/jenkins/job/pr-rangepos/770/

@gkossakowski
Copy link
Member

Just for FYI: I was about test those changes for performance but I realized that before leaving Lausanne I was doing some refactoring of my performance infrastructure so I'd get better accuracy for my benchmarks. I changed how data is being produced but not how it's being analyzed. I need to fix it it will take a while :-(

@paulp
Copy link
Contributor Author

paulp commented Oct 24, 2012

Take all the time you need, as long as you won't stand in the way of progress. This gives every sign of being better in terms of performance, and that's its least attractive feature.

@paulp
Copy link
Contributor Author

paulp commented Oct 29, 2012

Has it really only been 5 days? Feels like 50. The amount of work involved in a patch like this is obscene. (Nothing like a few undiscovered pattern matcher bugs to liven things up, too.) I would like to merge it.

@adriaanm
Copy link
Contributor

It wasn't a pattern matcher bug. I added a comment about why it failed last week: #1521 (comment)

@paulp
Copy link
Contributor Author

paulp commented Oct 29, 2012

It was a pattern matcher bug in the ordinary sense that a) there was a pattern and b) I tried to match with it and c) it didn't do the right thing. "pattern matcher bug" is not to my knowledge an appellation which requires a formal entrance exam.

@adriaanm
Copy link
Contributor

i believe the matcher's behaviour is as spec'ed. Those objects are actually different because the outer pointers are different.

@adriaanm
Copy link
Contributor

the cast I quoted above, localTyper.context1.asInstanceOf[d.Context], tricks the typechecker into believing d.Context =:= localTyper.context1.type, so it'll let the match go through, but since the object you're matching on is created once per instance of Typer (and we have two different ones here: d and localTyper) you'll actually be comparing an apple (d.LookupNotFound) and an orange (localTyper.LookupNotFound)

@paulp
Copy link
Contributor Author

paulp commented Oct 29, 2012

Okay, then why does the case class match? Shouldn't d.LookupNotFound() and localTyper.LookupNotFound() also be from different fruit bins?

@adriaanm
Copy link
Contributor

I'm going to say because the outer pointer cannot be tested, but it's a good question and I should find out.

@adriaanm
Copy link
Contributor

the green bytecode from #1521 (comment) seems to support my hypothesis

Trying to figure out why the fruits are on different trees now.

@paulp
Copy link
Contributor Author

paulp commented Oct 29, 2012

When can and cannot the outer pointer be tested, exactly? Should I now expect that moving a block of code between files without changing it or touching the visible semantics might start cases to start matching or stop matching? Have we considered what a bad idea this is?

Proposal: warn 100% of the time if a case would have matched, but does not due to the outer pointer check. Frequency with which this warning will be spurious noise: 0.1%. Frequency with which it will catch deadly silent not-matches where it was never intended that there be multiple "families" of some class: 99.9%. (I would like to meet the programmers for whom the outer pointer test is an intentional element of their design upon which correctness depends... because I have seen the old pattern matcher from the inside.)

Turns out putting a group of case classes at what feels like
the top level might not be top-level enough, like if your "top"
is Analyzer and you wind up with different outer pointers in
every instance of Typer. Moved the whole bundle to SymbolTable.
@adriaanm
Copy link
Contributor

Well, testing outer pointers has always been part of the spec. It was poorly implemented, but it is required for type soundness. Types selected on different prefixes should not be treated equal.

It is unfortunate that we cannot always test outer pointers (which was recently made harder by #954).

@adriaanm
Copy link
Contributor

That said, the type system will not even let you compare those classes unless you sneakily cast the prefix to something it is not.

@paulp
Copy link
Contributor Author

paulp commented Oct 29, 2012

Down comes the house of cards! https://issues.scala-lang.org/browse/SI-6583

@adriaanm
Copy link
Contributor

adriaanm commented Nov 1, 2012

PLS REBUILD ALL

(it seems it wasn't triggered on the last commit -- just to be sure...)

@scala-jenkins
Copy link

Started jenkins job pr-rangepos at https://scala-webapps.epfl.ch/jenkins/job/pr-rangepos/816/

@scala-jenkins
Copy link

Started jenkins job pr-scala-testsuite-linux-opt at https://scala-webapps.epfl.ch/jenkins/job/pr-scala-testsuite-linux-opt/1525/

@scala-jenkins
Copy link

jenkins job pr-scala-testsuite-linux-opt: Success - https://scala-webapps.epfl.ch/jenkins/job/pr-scala-testsuite-linux-opt/1525/

@scala-jenkins
Copy link

jenkins job pr-rangepos: Success - https://scala-webapps.epfl.ch/jenkins/job/pr-rangepos/816/

adriaanm added a commit that referenced this pull request Nov 1, 2012
Saving symbol lookup from typedIdent.
@adriaanm adriaanm merged commit a70c821 into scala:master Nov 1, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants