-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Introduce open
modifier on classes
#7471
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
0f1b69b
to
fad999a
Compare
This does not affect pattern matching exhaustivity (yet) since currently only abstract sealed classes and sealed traits are checked for exhaustivity, so defualt classes do not count. I wonder whether we should change that (?).
Also, make all synthetic classes produced in Definitions Open.
72279fc
to
3637127
Compare
3637127
to
8a1edce
Compare
Classes representing sum types need to be be abstract, which default classes are not. This partially reverts "Treat non-open classes as effectively sealed." d98c2d6.
d5b8522
to
1cba611
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
I think it's a good idea to mark open classes explicit. Open classes may be subject to different and/or more checks. It enables potential opportunities for interesting analysis and optimizations.
For example, for initialization, open classes may be subject to more strict checks to ensure modularity, while non-open classes can be checked by analysis to support more flexible initialization patterns and zero overhead in annotations.
One thing I'm not sure is about the scope of non-open classes: currently it's restricted to the same compilation-unit, but a natural physical boundary for programmers might be the same project, which is not a compiler concept.
|| sym == cls.owner | ||
|| sym.is(Package) | ||
|| sym.isType && isAccessible(sym.owner) | ||
!isAccessible(self.owner) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def foo: Unit = {
object O { class A }
class B extends O.A
}
According to the code, B
is not accessible from A
, is this intended?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would claim it is accessible!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I miss something here, I mean B.isInaccessibleChildOf(A) = true
, that is the value I get from the compiler compiling the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see now. Yes, this is a problem. I'll update the method and add a test.
Doesn't the JVM already do this, i.e. CHA (class hierarchy analysis)? If a class is never extended during the execution of the JVM, then its effectively the same as being |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
xcuse me for stepping into your PR without being invited; I commented on the discussion on the [hhttps://contributors.scala-lang.org/t/pre-sip-make-classes-sealed-by-default/3767/16?u=arkban] and was curious to see the PR.
|
||
- The language feature `adhocExtensions` is enabled for the extending class. This is typically enabled by an import statement in the source file of the extension: | ||
```scala | ||
import scala.language.adhocExtensions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to do this as annotation? IMHO a class-level annotation would make it clearer to the reader which class is doing the extending, and potentially make it easier to see what is being extended (since the class is in the extension list).
- `open` is a soft modifier. It is treated as a normal identifier | ||
unless it is in modifier position. | ||
- An `open` class cannot be `final` or `sealed`. | ||
- Traits or `abstract` classes are always `open`, so `open` is redundant for them. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the compiler emit a warning if you do open trait
or open abstract class
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No.
I mean compile-time analysis and optimization, instead of runtime. |
Right, I guess my general point is that "is there going to be a difference", as in is the compiler going to be able to handle more cases than the JVM will? |
* such extensions should be limited in scope and clearly documented. | ||
* That's why the language import is required for them. | ||
*/ | ||
object adhocExtensions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure adhocExtensions
is the best name to use here, it sounds like something related to extension methods. I suggest something more descriptive like openAllClasses
There are more platforms than the JVM, but irrespective of that, you can do static analysis for other purposes than optimization, like the initialization checker that @liufengyun is working on: https://contributors.scala-lang.org/t/improve-forward-reference-handling/3616/3 |
Regarding the project-scope VS compilation-unit-scope problem, I'm thinking if the compiler can accept an option
It has the following benefits:
Edited: one technical difficulty is how to deal with incremental compilation & child registration. That is indeed a subtle problem. |
Introducing |
For a description of changes, see https://github.com/dotty-staging/dotty/blob/add-open-class/docs/docs/reference/other-new-features/open-classes.md