In response to some concerns around the situation for RAII structs going into closures, I am proposing a resolution to this that will be a language-wide guarantee, not an ultra-specific, not-a-guarantee solution.
https://github.com/dlang/dmd/issues/18704
If a struct destructor is annotated with an attribute @stackonly
it may only be called if the this
pointer is allocated on the stack. It does not overload.
struct RAII {
~this() @stackonly {}
}
void foo() {
RAII* gc = new RAII; // Error: RAII can only be cleaned up if it is on the stack
scope RAII* stack1 = new RAII; // ok
RAII stack2 = RAII(); // ok
}
The attribute is inferred based upon the fields.
struct Wrapper {
RAII raii;
~this() /* @stackonly */ {}
}
As closure creation can see this, no variable that is stack only, cannot be moved into a closure.
Currently D does not model GC vs non-GC pointers, therefore moving into pointers is also disallowed.
RAII* ptr = ...;
*ptr = RAII(); // Error
But only in @safe
code. For @system
code, it is allowed to by-pass this restriction for data structures.