On Friday, 16 November 2018 at 12:59:22 UTC, aliak wrote:
Adding @trusted to declaration of opDispatch gets rid of @safe
error but I still get "Error: @nogc function D main cannot call
non-@nogc function". And going through the codebase and
figuring out where to add @trusted is *very* cumbersome.
I can't figure out how to make this work. The ideal way would
be just a debug_print() function that works in nogc and safe
code. I.e. does not affect the attribute inference of templates.
As Zoadian points out, you can now (since 2.079:
https://dlang.org/changelog/2.079.0.html#bugfix-list) shamelessly
call @nogc inside debug blocks.
To get at where the problematic areas were in the code in
question though, it's as follows:
auto assumeNoGC(T)(T t) { // point 1
import std.traits;
enum attrs = functionAttributes!T | FunctionAttribute.nogc;
// point 2:
return cast(SetFunctionAttributes!(T, functionLinkage!T,
attrs)) t;
}
At 'point 1', you just take by value. If `t` ends up being a
closure, D will allocate. That's where it breaks the @nogc.
Solution:
auto assumeNoGC(T)(return scope T t) { /* ... */ }
Now you take (and return) a `scope` t, in that case when `t` is a
closure D won't allocate it on the GC heap.
At 'point 2' you make an un-@safe cast, that's where it breaks
@safe. Given that the whole deal is just a debugging hack, you
could mark the whole function @trusted:
auto assumeNoGC(T)(return scope T t) @trusted { /* ... */ }