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
Don't allow objects to be cloned #3764
Comments
Imported From: https://issues.scala-lang.org/browse/SI-3764?orig=1 |
@lrytz said: |
@paulp said: |
Naftoli Gugenheim (naftoligug) said: |
@adriaanm said: |
@adriaanm said: |
@szeiger said: object ObjectIdentityTest {
def main(args: Array[String]) { new ObjectIdentityTest() }
abstract class Base extends Cloneable {
override def clone(): Base = super.clone().asInstanceOf[Base]
def foo = { println(" hashCode = "+this.hashCode()); true }
def bar: Unit
}
object A extends Base { def bar = List(1).filter(_ => foo) }
}
class ObjectIdentityTest {
import ObjectIdentityTest._
println("Original A:")
A.foo
A.bar
val clonedA = A.clone()
println("Cloned A:")
clonedA.foo
clonedA.bar
} |
Since the statute of limitations has run out, the linked PR just lints it. Thus, the resolution of this ticket is as lrytz suggested: except it's just a lint. Thankfully, there is no need to deprecate |
When an "object" is placed into a package or another such object, it is assumed to be a singleton and the compiler apparently optimizes "this" references in closures within methods that object to refer to the singleton.
This assumption is incorrect when the object is clone()d, as demonstrated by this snippet:
The output looks like this:
For B and C this is as expected but for object A, calling bar() on a
clone calls foo() on the original object.
The compiler can recognize this situation because the object in question extends java.lang.Cloneable. In this case, the object should not be assumed to be a singleton (with regards to the optimizations the compiler may perform).
The text was updated successfully, but these errors were encountered: