On Saturday, 10 March 2018 at 17:43:06 UTC, Simen Kjærås wrote:
I'm not sure how fixable this is, but I am sure that there's plenty of benefit to being able to write code like this:

struct S {
    int n, m;
    SomeType!(() => n + m) a;
}

over this:

struct S {
    int n, m;
    auto a() { return SomeType!(() => n + m)(); }
}

Anyways, I filed a bug for it:
https://issues.dlang.org/show_bug.cgi?id=18587

Actually, this is not fixable. If we consider for a moment the internals of SomeType in the above code, it's something like this:

struct SomeType(alias fn) {
    S* context;
}

The full layout of S then becomes this:

struct S {
    int n;
    int m;
    S* a.context; // points to 'this'.
}

Since structs in D are defined to be movable by blitting only, with no cleanup afterwards, internal pointers are a no-no. Ref https://dlang.org/spec/garbage.html:

Do not have pointers in a struct instance that point back to the same instance. The trouble with this is if the instance gets moved in memory, the pointer will point back to where it came from, with likely disastrous results.

One possible solution would be for the above code to generate the function a() instead of making 'a' a member. This has its own set of issues, though - suddenly something that looks like a member isn't one, and its address can't be taken, it can't be passed by ref, etc.

--
  Simen

Reply via email to