Prevent struct going into heap memory

Richard Andrew Cattermole (Rikki) richard at cattermole.co.nz
Sun Jul 20 17:04:11 UTC 2025


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.

```d
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.

```d
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.

```d
RAII* ptr = ...;
*ptr = RAII(); // Error
```

But only in ``@safe`` code. For ``@system`` code, it is allowed 
to by-pass this restriction for data structures.


More information about the dip.ideas mailing list