-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Too much redundant lazy vals code. #676
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
The issue seems to be that dotty, unlike scalac, always generates companion objects for classes. I guess that the problem is that class Foo
object Test {
def test = {
val x = new Foo {}
}
} Becomes after package <empty> {
class Foo() extends Object() {}
final lazy module val Foo: Foo$ = new Foo$()
final module class Foo$() extends Object() { this: Foo.type =>}
final lazy module val Test: Test$ = new Test$()
final module class Test$() extends Object() { this: Test.type =>
def test: Unit = {
val x: Foo = {
final class $anon() extends Foo() {}
final lazy module val $anon: Object{...} = new Object{...}()
final module class $anon$() extends Object() { this: $anon.type =>}
new Foo{...}(): Foo
}
()
}
}
} So in the end we get: result of try/anonclass.scala after genBCode:
package <empty> {
class Foo extends Object {
def <init>(): Unit = {
super()
()
}
}
final lazy module val Foo: Foo$ = new Foo$()
final module class Foo$ extends Object { this: Foo$ =>
def <init>(): Unit = {
super()
()
}
}
final lazy module val Test: Test$ = new Test$()
final module class Test$ extends Object { this: <notype> =>
def <init>(): Unit = {
super()
()
}
def test(): Unit = {
val x: Foo = {
lazy var $anon$lzy1: dotty.runtime.LazyRef = new dotty.runtime.LazyRef()
new Foo{...}(): Foo
}
()
}
private def $anon$lzyINIT1$1($anon$lzy1$1: dotty.runtime.LazyRef):
Object{...}
=
$anon$lzy1$1.synchronized(
if $anon$lzy1$1.initialized() then $anon$lzy1$1.value() else {
$anon$lzy1$1.initialized_=(true)
$anon$lzy1$1.value_=(new Object{...}())
$anon$lzy1$1.value()
}
).asInstanceOf[Object{...}]
private final lazy <accessor> module def $anon$1(
$anon$lzy1$2: dotty.runtime.LazyRef
): Object{...} =
(if $anon$lzy1$2.initialized() then $anon$lzy1$2.value() else
Test.$anon$lzyINIT1$1($anon$lzy1$2)
).asInstanceOf[Object{...}]
}
private final <static> class $anon$2 extends Foo {
def <init>(): Unit = {
super()
()
}
}
private final module <static> class $anon$1$1$ extends Object {
this: Object{...} =>
def <init>(): Unit = {
super()
()
}
}
} |
I know how to fix this, additionally fixing #549. I'll do it after getting to the bottom of patmat bugs. |
@smarter, you are presenting a different example, where the behavior is correct and required. In your case you have a non-used lazy val inside a method. It doesn't cost much during tree creation and will be eliminated by backend(private non-used methods). |
It's correct to mitigate such example: def method = {
class A(var b: B) {
@volatile lazy val a1: Int = {println("a1"); b.b1}
@volatile lazy val a2: Int = {println("a2"); 1}
}
class B(a: A) {
@volatile lazy val b1: Int = {println("b1"); a.a2}
}
val as = Array.fill(1000)(new A(null))
val bs = as.map(x => new B(x))
(as zip bs).forall(x => x._1.b = x._2)
val runnableA = new Runnable {
def run(): Unit = as.foreach(_.a1)
}
val runnableB = new Runnable {
def run(): Unit = bs.foreach(_.b1)
}
new Thread(runnableA).start
new Thread(runnableB).start
} |
Modules which are entirely synthetic now are eager This fix additionally makes inner objects of other objects remain static classes, instead of becoming lazy vals.
Modules which are entirely synthetic now are eager This fix additionally makes inner objects of other objects remain static classes, instead of becoming lazy vals.
Modules which are entirely synthetic now are eager This fix additionally makes inner objects of other objects remain static classes, instead of becoming lazy vals.
Fixed by #706 a while ago, closing. |
Improved the fix of bug scala#676 - only emit interface call if the target is Java annotation and not just arbitrary attribute
Improved the fix of bug scala#676 - only emit interface call if the target is Java annotation and not just arbitrary attribute
Have a look at copnstructors.scala (only one example of many). We find:
This is all for a module that was not mentioned in source and that is in fact empty! This is wrong on many levels
The text was updated successfully, but these errors were encountered: