-
Notifications
You must be signed in to change notification settings - Fork 14
Use default methods in our trait encoding #35
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
Comments
Omitting forwarders has a benefit for binary compatibility in this situation. I think it should be our preferred approach.
|
+1, note that even in the scenario where B does not extend A, but where |
as I said on Slack, the scenario I'm concerned about is:
whoa, you say, "undefined"? yes, JSR 335 says:
|
Adriaan found this, which may indicate this is not so undefined and indeterministic after all: https://jvilk.com/blog/java-8-specification-bug/ |
How does this handle fields in traits? Are default methods going to take a |
Fields will work as today. Default methods on interfaces take the |
At least in dotty they do not. On 14 August 2015 12:32:21 Iulian Dragos [email protected] wrote:
|
Copying Adriaan's mail here. Now that work on the second main feature of 2.12 is under way -- compiling traits to interfaces -- a quick update. Thanks to the Dotty compiler, where this is already implemented, we have confidence that we can compile all Scala trait to interfaces! Because Scala member lookup semantics are different from Java's, we will have to generate a fair amount of synthetic code in classes that extend traits to make sure we get Scala's linearization semantics and not Java's "default methods are not called when an instance method is available". See the linked gist for an example. Most of the current trait encoding carries over directly. The most exciting simplificaiton is that we no longer need the trait's implementation class (T$class)! As it was mostly a holder for the bodies of concrete trait methods, which become default methods in the interface. (We'll need to deal with initialization methods for lazy vals and objects slightly differently, but no biggy.) When linearization order is known (at the class that inherits traits), we can add fields, implement super/outer/field/object/lazy val accessors and enforce the linearization order. For super accessors, for example, the meaning of a super call The linearization order is codified by overriding every method that has an implementation in one of the base classes/traits, with a method that calls the correct super-method. This means binary compatibility suffers in a similar way as the current trait encoding, although you will be able to introduce new methods in traits without incurring a linkage error, the runtime behavior will only be correct if there's no overriding instance method (see the gist above). |
Java 8 allows interfaces to contain default implementations of methods. This is done by
removing a restriction in the bytecode, interface methods may now have a code attribute.
Current trait encoding
$this
as an extra parameterProposed encoding
to the same method as the forwarder would target.
super[Trait].method
, we can useinvokespecial
to call the default implementation of interface method.
Benefits
JFunctionN
interfaces initially used to back Scala 2.12 lambdasNon Benefits
Steps
AddInterfaces
, impl classes, and redirect references to impl methods to default methods #37 Do away with impl classesThe text was updated successfully, but these errors were encountered: