-
Notifications
You must be signed in to change notification settings - Fork 14
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
Clean up interaction between module desugaring and mixin #42
Comments
Current transform in mixin for: trait T {
object O
}
class C extends T Is: --- abstract trait T extends Object { (Selection)
+++ (clipboard)
@@ -1,17 +1,35 @@
+package <empty> {
abstract trait T extends Object {
<stable> def O(): T$O.type
};
class C extends Object with T {
+ @volatile <synthetic> private[this] var O$module: T$O.type = _;
+ private def O$lzycompute(): T$O.type = {
+ {
+ C.this.synchronized({
+ if (C.this.O$module.eq(null))
+ {
+ C.this.O$module = new T$O.type(C.this);
+ ()
+ };
+ scala.runtime.BoxedUnit.UNIT
+ });
+ null
+ };
+ C.this.O$module
+ };
+ <stable> def O(): T$O.type = if (C.this.O$module.eq(null))
+ C.this.O$lzycompute()
+ else
+ C.this.O$module;
def <init>(): C = {
C.super.<init>();
- C.this.$asInstanceOf[T$class]()./*T$class*/$init$();
+ T$class./*T$class*/$init$(C.this);
()
}
};
- abstract trait T$class extends Object with T {
- @volatile <synthetic> var O$module: T$O.type = _;
- <stable> def O(): T$O.type = new T$O.type(T$class.this);
- def /*T$class*/$init$(): Unit = {
+ abstract trait T$class extends {
+ def /*T$class*/$init$($this: T): Unit = {
()
}
}; |
Quoth @lrytz:
|
Starting work here: scala/scala@scala:2.12.x...retronym:topic-trait-defaults-module |
I was thinking if there was a way to reduce how much code we have to inject into every class that extends a trait, but synchronization and the second null check make it hard to imagine how. |
Ideally, the class would just have a field and trivially implement straight getter/setters. |
Maybe something like:
Not sure if it's worth it, or even if it meets the same criteria regarding bytecode size, JITability,... |
A variation: abstract trait T extends Object {
<stable> def O(): T$O.type = {
val mod1 = T.this.O$module
if (T.this.O$module.eq(null))
T.this.synchronized {
val mod2 = O$module()
O$module_=(if (mod2 eq null) new T$O.type(this) else mod2)
}
else mod1
<stable> <notprivate> def O$module(): T$O.type
<notprivate> def O$module_=(o: T$O): Unit
}
class C extends Object with T {
@volatile <synthetic> private[this] var O$module: T$O.type = _;
<stable> <notprivate> def O$module(): T$O.type = C.this.O$module
<notprivate> def O$module_=(o: T$O): Unit = this.O$module = o
} I believe the semantics are the same, but it has the potential for worse performance. In the status quo, a call to |
Here's a little progress: retronym/scala#18 |
No description provided.
The text was updated successfully, but these errors were encountered: