Thread overview
May 02
Often, GC is nice but collections should be avoided in an inner loop. `@nogc` is too restrictive because may be fine to e.g., allocate an `Exception` before throwing it, and programmers are aware that such allocations are happening.

A somewhat more insidious case is implicit allocation, because even when programs look like they do need to allocate, they may in fact allocate due to the compiler's escape analysis being too weak.

For example, there is no reason for the following program to allocate with the GC, but it does implicitly allocate a closure:

```d
void main(){ // errors with @nogc
    auto y=2;
    assert(iota(10).filter!((x)=>x%y!=0).sum==25);
}
```

In case the GC is disabled, such imprecise escape analysis in an inner loop may result in a memory leak.

Proposal: Add `pragma(explicit_gc)`. Functions marked with this pragma will non-transitively error out on implicit GC allocations. This is a useful tool to check expectations about escape analysis precision.
May 02
On 02/05/2024 1:45 PM, Timon Gehr wrote:
> Proposal: Add `pragma(explicit_gc)`. Functions marked with this pragma will non-transitively error out on implicit GC allocations. This is a useful tool to check expectations about escape analysis precision.

I have been proposing this for years under the name ``@localnogc``.

Although I would disallow new'ing an exception with it annotated.

At some point I want to do an attribute cleanup DIP.

Make all attributes positive, include negation form, introduce the throws set and of course ``@localnogc`` and ``@notls``.
May 02
On 5/2/24 03:45, Timon Gehr wrote:
> 
> A somewhat more insidious case is implicit allocation, because even when programs look like they do

not. do not need to allocate. x)

> need to allocate, they may in fact allocate due to the compiler's escape analysis being too weak.

May 02
On 5/2/24 03:52, Richard (Rikki) Andrew Cattermole wrote:
> On 02/05/2024 1:45 PM, Timon Gehr wrote:
>> Proposal: Add `pragma(explicit_gc)`. Functions marked with this pragma will non-transitively error out on implicit GC allocations. This is a useful tool to check expectations about escape analysis precision.
> 
> I have been proposing this for years under the name ``@localnogc``.
> ...

I see. I do think that making it a `pragma` may be more fruitful, because a function attribute would typically be part of the type of a function. However, the interface of the function is not actually affected by such checks.

> Although I would disallow new'ing an exception with it annotated.
> ...

I guess this check could be bypassed using a nested function if needed, but I think explicit allocations are simply not an issue as they do not defy expectations.

> At some point I want to do an attribute cleanup DIP.
> 
> Make all attributes positive, include negation form, introduce the throws set and of course ``@localnogc`` and ``@notls``.

Sounds good.
May 02
On 02/05/2024 1:59 PM, Timon Gehr wrote:
>     Although I would disallow new'ing an exception with it annotated. ...
> 
> I guess this check could be bypassed using a nested function if needed, but I think explicit allocations are simply not an issue as they do not defy expectations.

My thinking is that it is a non-transitive version of ``@nogc``.

No other changes other than things that affect transitivity (such as not being part of the signature).

Keep it simple, easy to explain and tie it into existing language feature.
May 04
On 5/2/24 03:45, Timon Gehr wrote:
> Often, GC is nice but collections should be avoided in an inner loop. `@nogc` is too restrictive because may be fine to e.g., allocate an `Exception` before throwing it, and programmers are aware that such allocations are happening.
> 
> A somewhat more insidious case is implicit allocation, because even when programs look like they do need to allocate, they may in fact allocate due to the compiler's escape analysis being too weak.
> 
> For example, there is no reason for the following program to allocate with the GC, but it does implicitly allocate a closure:
> 
> ```d
> void main(){ // errors with @nogc
>      auto y=2;
>      assert(iota(10).filter!((x)=>x%y!=0).sum==25);
> }
> ```
> 
> In case the GC is disabled, such imprecise escape analysis in an inner loop may result in a memory leak.
> 
> Proposal: Add `pragma(explicit_gc)`. Functions marked with this pragma will non-transitively error out on implicit GC allocations. This is a useful tool to check expectations about escape analysis precision.

Merged into OpenD: https://github.com/opendlang/opend/pull/69

Can be cherry-picked from there.