-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Conversation
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.
Tests are currently part of #4616, in particularly |
Avoid "pure expression does nothing in statement position" warnings.
Hi Georg, can you have a look at this and see how it relates to your notion of stability? |
@gsps Can you give this a quick review please? I believe it would simplify things if we had this merged now. |
I'm focused on the other deadline, but I'll try to review this right after. |
Merging now, since not doing so would complicate things going forward. |
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 areNoInits
. Constructors of pure classes are markedstable
, which means that anew
expression can now be pure. Currently purity is only indicated for Dotty classes and a few classes inDefinitions
.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.