On Tuesday, 16 January 2024 at 13:45:22 UTC, FeepingCreature wrote:
Am I safe as long as I don't do something like, pass `&sendThing` as an argument to `std.concurrency.receive`?

Yes.

Thank you.

And to make sure I don't misunderstand the spec; in the case I *do* have a delegate I want to pass elsewhere, and `scope dg = &myFun;` *does* compile, passing that `dg` around won't allocate a closure?

```d
void foo(Thing thing) @nogc
{
    void sendThing(const string where, int i)
    {
        send(thing, where, i);
    }

    receiveTimeout(Duration.zero, &sendThing);
}
```

The above naturally won't compile because `std.concurrency.receiveTimeout` requires the garbage collector, but notably in the error message, this is included;

```
onlineapp.d(10): Error: function `onlineapp.foo` is `@nogc` yet allocates closure for `foo()` with the GC onlineapp.d(12): `onlineapp.foo.sendThing` closes over variable `thing` at onlineapp.d(10)
```

If I make a `scope` variable of the delegate and pass *it* to `receiveTimeout`, there no longer seems to be any mention of the closure in the error (given 2.092 or later).

```d
void foo(Thing thing) @nogc
{
    void sendThing(const string where, int i)
    {
        send(thing, where, i);
    }

    scope scopeSendThing = &sendThing;
    receiveTimeout(Duration.zero, scopeSendThing);
}
```

Ignoring that it doesn't compile for other reasons; provided `scope scopeSendThing = &sendThing;` compiles -- as in, `&sendThing` is eligible for `scope` -- is this a valid workaround?

Reply via email to