Bug 6741 – implicit casting of pure-function delegate result to immutable breaks immutability.

Status
NEW
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
Other
OS
All
Creation time
2011-09-29T10:46:04Z
Last change time
2024-12-13T17:56:32Z
Assigned to
No Owner
Creator
Steven Schveighoffer
Moved to GitHub: dmd#18372 →

Comments

Comment #0 by schveiguy — 2011-09-29T10:46:04Z
For example: class A { int n; void delegate( ) dg; void foo() {n++;} } pure A createAnA( int n ) { A result = new A; result.n = n; result.dg = &result.foo; return result; } void main( ) { immutable A tmp = createAnA( 3 ); assert( tmp.n == 3 ); tmp.dg(); assert( tmp.n == 4 ); } Because delegates cannot be cast, I think it should be illegal to cast a delegate-containing object or struct to immutable implicitly. An explicit cast should be required.
Comment #1 by lt.infiltrator — 2014-03-19T21:20:35Z
Why is this a bug? With the delegate, it is the pointer itself which becomes immutable, not the pointed-to function. This appears to be correct behaviour. Furthermore, disallowing any delegate-containing object to be immutable seems unnecessarily strict for no (?) benefit.
Comment #2 by schveiguy — 2014-03-20T12:57:35Z
It's a bug because when the object is cast implicitly to immutable, it does not affect the context pointer. In essence, the delegate captures the instance when it was mutable. Normally, implicitly casting a pure return to immutable is OK because immutable is transitive. Since a strong pure function cannot have side effects, the return must be the only reference to it. However, if it contains a reference to itself via a delegate, that reference does NOT get cast to immutable. Why do you think the given code is correct behavior? I should never be able to do this without casts: immutable a = ... assert(a.n == 3); ... assert(a.n == 4); BTW, I do not say that a class with delegate members should not be allowed to be immutable, I'm saying that it should not *implicitly* cast to immutable. In other words, the code would be allowed if you did: auto tmp = cast(immutable(A))createAnA(3); In this case, you are telling the compiler "I know what I'm doing."
Comment #3 by robert.schadek — 2024-12-13T17:56:32Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18372 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB