September 15, 2023
https://issues.dlang.org/show_bug.cgi?id=24147

          Issue ID: 24147
           Summary: Struct destructors should not allow GC
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: dmd
          Assignee: nobody@puremagic.com
          Reporter: lance@lancebachmeier.com

It is possible to do things like string concatenation inside a destructor. That shouldn't be allowed to compile because it is not valid code. The compiler should treat destructors as @nogc whether they're marked that way or not.

Example code:

import std.stdio;
struct Predictable
{
    string id;
    this(string _id)
    {
        writeln("Constructor ", _id);
        id = _id;
    }
    ~this()
    {
        writeln("Destructor " ~ id);
    }
}

void main()
{
    Predictable[] result;
    result ~= Predictable("1");
    writeln("result: ", result);
}

Dies with

Constructor 1
result: [Predictable("1")]
core.exception.InvalidMemoryOperationError@src/core/lifetime.d(126): Invalid
memory operation

Putting @nogc on the destructor, the compiler gives this message:

onlineapp.d(12): Error: `@nogc` destructor `onlineapp.Predictable.~this` cannot
call non-@nogc function `std.stdio.writeln!string.writeln`
/dlang/dmd/linux/bin64/../../src/phobos/std/stdio.d(4251):        which calls
`std.stdio.trustedStdout`
onlineapp.d(12): Error: cannot use operator `~` in `@nogc` destructor
`onlineapp.Predictable.~this`

https://run.dlang.io/is/7fZepu

--