May 27, 2019
On Monday, 27 May 2019 at 00:41:22 UTC, Manu wrote:
> Well I'm obviously implementing a tagged union.
> The language just needs to make the feature available, and let me wrap it up.

IIRC Bearophile suggested that the struct could provide a function or some mechanism that would tell the runtime what type the union contained. But Andrei didn't like it.

Some sort of "type-switch" statement in the union with a conditional that is allowed to reference fields in the surrounding struct would be a possibility.

The real problem isn't that one cannot come up with a decent solution, but that the semantics of C has been subsumed, and extended.

May 26, 2019
On Sun, May 26, 2019 at 7:55 PM Ola Fosheim Grøstad via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On Monday, 27 May 2019 at 00:41:22 UTC, Manu wrote:
> > Well I'm obviously implementing a tagged union.
> > The language just needs to make the feature available, and let
> > me wrap it up.
>
> IIRC Bearophile suggested that the struct could provide a function or some mechanism that would tell the runtime what type the union contained. But Andrei didn't like it.

Right, that's a terrible idea. Who's to say that's how the union is used.

> Some sort of "type-switch" statement in the union with a conditional that is allowed to reference fields in the surrounding struct would be a possibility.

Sounds like a lib to me.

> The real problem isn't that one cannot come up with a decent solution, but that the semantics of C has been subsumed, and extended.

I don't really think there's a problem here, just @disable the default copy/postblit/destructor in the presence of a union, and also make any access to a member of a union un-@safe. The rest will fall out naturally.

May 27, 2019
On Monday, 27 May 2019 at 04:52:14 UTC, Manu wrote:
> I don't really think there's a problem here, just @disable the default copy/postblit/destructor in the presence of a union, and also make any access to a member of a union un-@safe. The rest will fall out naturally.

Depends on how strict you want to be.  In terms of correctness you shouldn't allow anything with a destructor in a union in the first place.

May 26, 2019
On Sun, May 26, 2019 at 10:20 PM Ola Fosheim Grøstad via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On Monday, 27 May 2019 at 04:52:14 UTC, Manu wrote:
> > I don't really think there's a problem here, just @disable the default copy/postblit/destructor in the presence of a union, and also make any access to a member of a union un-@safe. The rest will fall out naturally.
>
> Depends on how strict you want to be.  In terms of correctness you shouldn't allow anything with a destructor in a union in the first place.

Why? Then it would be impossible to use unions to write anything useful.

May 27, 2019
On Saturday, 25 May 2019 at 23:15:05 UTC, Manu wrote:
> So, it seems that if an object has a postblit and a copy constructor, the postblit is preferred.
>
> It also seems that if an object has a copy constructor and a MEMBER with a postblit, then object has a postblit generated which calls through to the member, and that is preferred.
>
> I have also noticed that if you have a union containing an item with a postblit, the postblit is always called, even if the item in the union is not valid:
>
That's a bug, but I think that it's not going to be fixed since the postblit
should be deprecated soon.

> struct S(T)
> {
>   union {
>     int x = 0;
>     T y = void;
>   }
>   bool isT = false;
> }
>
> S a;
> S b = a; // calls `y's postblit, even though it's `isT` is false and
> the object is `void` initialised...
>
> So, it's very hard to craft a tool like 'S', when the supplied T might have a postblit and ruin everything. What are my options here?
>
Currently, you don't have any options. As I see it, there are 3 possible solutions:

1. Change the semantics of `disable this(this)` from "object is not copyable"
to "object is not copyable through postblit". This way we can exclude postblits
but allow copies using the copy constructor.

2. Check if T has postblit with a static if (via traits) and define the copy
constructor only if T does not have a postblit.

3. Issue a deprecation if T has a postblit.

Essentially, there is no clear way in how you can mix object with postblits and objects with copy constructor

> Also, `hasElaborateCopyConstructor` is broken now. It should know about copy ctor's.


May 27, 2019
On Mon, May 27, 2019 at 2:11 AM RazvanN via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On Saturday, 25 May 2019 at 23:15:05 UTC, Manu wrote:
> > So, it seems that if an object has a postblit and a copy constructor, the postblit is preferred.
> >
> > It also seems that if an object has a copy constructor and a MEMBER with a postblit, then object has a postblit generated which calls through to the member, and that is preferred.
> >
> > I have also noticed that if you have a union containing an item with a postblit, the postblit is always called, even if the item in the union is not valid:
> >
> That's a bug, but I think that it's not going to be fixed since
> the postblit
> should be deprecated soon.

How soon? Is this another case of "just wait 10 more years before you
can use D"?
It looks like it needed to be fixed about 10 years ago, so no time
like the present! :)

> > struct S(T)
> > {
> >   union {
> >     int x = 0;
> >     T y = void;
> >   }
> >   bool isT = false;
> > }
> >
> > S a;
> > S b = a; // calls `y's postblit, even though it's `isT` is
> > false and
> > the object is `void` initialised...
> >
> > So, it's very hard to craft a tool like 'S', when the supplied T might have a postblit and ruin everything. What are my options here?
> >
> Currently, you don't have any options. As I see it, there are 3 possible solutions:
>
> 1. Change the semantics of `disable this(this)` from "object is
> not copyable"
> to "object is not copyable through postblit". This way we can
> exclude postblits
> but allow copies using the copy constructor.

Good idea, and easy to implement in minutes!
It's not a solution though, but it is one piece in a larger puzzle.

> 2. Check if T has postblit with a static if (via traits) and
> define the copy
> constructor only if T does not have a postblit.

This is useless, because if S does not have a copy constructor, the
object can't work under any circumstances.
It also wouldn't solve the problem, since the union item's destructor
is still called by the same rules, so copying is not the only issue
here.

> 3. Issue a deprecation if T has a postblit.
>
> Essentially, there is no clear way in how you can mix object with postblits and objects with copy constructor

Right, they shouldn't be mixed.
In this case, I could move forwards if the union issue was fixed though.
If T in the union did NOT call field-copy and field-destruction (which
is just a bug!), then I could static-check and manually handle the 2
cases of whether T has a copyctor or a postblit in the implementation
of the copy ctor of S, so I could reconcile the difference with some
extra work in S.

I think the only path to solution is to fix the issue with unions, and that absolutely needs to happen anyway regardless.
May 28, 2019
On Saturday, 25 May 2019 at 23:15:05 UTC, Manu wrote:

> I have also noticed that if you have a union containing an item with a postblit, the postblit is always called, even if the item in the union is not valid:

Just for the record, I've made a PR that fixes this: https://github.com/dlang/dmd/pull/9909

Hope this will be of help for you, Manu.


May 28, 2019
On Tue, May 28, 2019 at 6:30 AM RazvanN via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On Saturday, 25 May 2019 at 23:15:05 UTC, Manu wrote:
>
> > I have also noticed that if you have a union containing an item with a postblit, the postblit is always called, even if the item in the union is not valid:
>
> Just for the record, I've made a PR that fixes this: https://github.com/dlang/dmd/pull/9909
>
> Hope this will be of help for you, Manu.

OMG so good!
Bonus points if any access to members of a union is un-@safe...
1 2
Next ›   Last »