dmd icon indicating copy to clipboard operation
dmd copied to clipboard

Nested `@nogc` functions may allocate

Open limepoutine opened this issue 2 months ago • 0 comments

struct Int
{
	int j;
}

auto apply(alias f)(Int i) => f(i.j);

struct B(alias f1, alias f2)
{
	int k;

	void allocs() @nogc
	{
		// Allocates from GC heap to save an outer context pointer
		f1(Int(k));
		Int(0).apply!(_ => f2(Int(k)));
	}
}

void neverAllocs(void delegate() @nogc dg) @nogc
{
	dg();
}

void main()
{
	Int i;
	Int j;

	scope f1 = (in Int k) @nogc
	{
		i = k;
	};

	scope f2 = (in Int k) @nogc
	{
		j = k;
	};

	auto b = B!(f1, f2)();

	b.allocs();             // May cause GC
	neverAllocs(&b.allocs); // May cause GC
}

Accessing this from two layers of nested contexts forces the compiler to save a context pointer using GC memory, even when it does not escape and the parent function is marked with @nogc.

limepoutine avatar Oct 15 '25 18:10 limepoutine