Skip to content

Some Rudimentary Tracking of Class Purity #4710

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 7 commits into from
Jul 8, 2018

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Jun 23, 2018

This PR breaks out the commits in #4616 that let us establish a rudimentary notation of class purity. A class does not need an initalizer (indicated by the NoInits flag) if it only contains method and type definitions or abstract declarations of any kind and if it does not pass arguments to its parent class. A class is pure if it and all its baseclasses are NoInits. Constructors of pure classes are marked stable, which means that a new expression can now be pure. Currently purity is only indicated for Dotty classes and a few classes in Definitions.

This scheme is admittedly quite rudimentary but it allows us to classify typical case classes that define data types as pure. This in turn is necessary to reduce projections of such data classes occurring in transparent methods.

odersky added 6 commits June 23, 2018 14:21
A class is pure for the purpose of reducing projections in inlinig
if none of its baseclasses has an initializer.

To make this robust wrt compilation order, we need to move computation of
NoInits flags from Typer to the class completer.

# Conflicts:
#	compiler/src/dotty/tools/dotc/typer/Inliner.scala
Four improvments:

 1. Applications of stable and pure functions to pure arguments are pure.
    This is important since constructors of pure classes are marked Stable.
 2. New(...) expressions are pure (any side effects are caused by the constructor
    application).
 3. Module values are pure of their module classes are pure.
 4. scala.Product and scala.Serializable are assumed to be pure. Therefore,
    case classes can also be pure.

These predictons remove most remaining unused bindings in the run/typelevel.scala test.
Don't issue a "pure expression does nothing in statement position" for self and
super constructor calls. They are conceptually unit-returning in this position anyway.
Methods with default arguments in traits generate defender methods, so the
trait cannot be a pure interface. Checking def kinds earlier in Namer rather
than Typer exhibited that special case.
Constructors (and potentially, in the future, other methods) can have the stable
flag set. We need to adapt ExtractAPI to this change.
We declare a class (not a trait) impure if it passes arguments to its parents.
This is a very conservative estimate. It's hard to do better, though, since
parent expressions are not always typed when we need to decide class purity.
So we cannot use `isPureExpr` on argument expressions to find out more.
@odersky
Copy link
Contributor Author

odersky commented Jun 23, 2018

Tests are currently part of #4616, in particularly neg/typelevel.scala. We verify purity by observing that inlining took place.

Avoid "pure expression does nothing in statement position" warnings.
@odersky odersky requested a review from gsps June 25, 2018 15:52
@odersky
Copy link
Contributor Author

odersky commented Jun 25, 2018

Hi Georg, can you have a look at this and see how it relates to your notion of stability?

@odersky
Copy link
Contributor Author

odersky commented Jul 4, 2018

@gsps Can you give this a quick review please? I believe it would simplify things if we had this merged now.

@Blaisorblade
Copy link
Contributor

I'm focused on the other deadline, but I'll try to review this right after.

@odersky
Copy link
Contributor Author

odersky commented Jul 8, 2018

Merging now, since not doing so would complicate things going forward.

@odersky odersky merged commit 346b8fa into scala:master Jul 8, 2018
@Blaisorblade Blaisorblade deleted the add-class-purity branch July 9, 2018 10:06
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