Instantiation of nested structs should be allowed outside their parent scope

Stanislav Blinov stanislav.blinov at gmail.com
Tue Nov 9 18:41:53 UTC 2021


On Tuesday, 9 November 2021 at 17:18:31 UTC, Timon Gehr wrote:
> On 09.11.21 17:51, Stanislav Blinov wrote:
>> On Tuesday, 9 November 2021 at 16:34:26 UTC, Timon Gehr wrote:
>> 
>>> Sure, which is what I said (do it = copy things). But why 
>>> would you want the check to behave differently from actual 
>>> code that copies things?
>> 
>> ? Because the check only needs to tell me if copying throws or 
>> not.
>
> For the specific issue we have been discussing, it seems to me 
> that copying does not work at all, independent of whether it's 
> throwing or not. It should just work.

It does work just fine. Can copy NestedThatFails within its 
context. Can copy it to outside of its context too if need be, 
with copyEmplace. Before you ask "why not just use copyEmplace 
for the test then?" the answers are 2:

1) it's '@system', so I won't be able to devise an isSafe... test 
out of it, and
2) look at its source code, the very first static if inside ;)

>> That specific check, that is. Nothing else. Because that 
>> information drives how I allocate or how, exactly, do I copy 
>> things. Other checks drive other things. BTW, I forgot to show 
>> one more thing, that is that isNothrowCopyable reduces to 
>> isCopyable for BetterC. Not Phobos' isCopyable, but an 
>> isCopyable that tests distinct types because qualifier hell. 
>> Which should be that same union test from before, only without 
>> attributes. But, alas, it is not.
>> ...
>
> What's different?

I don't understand what you're asking. What's different where?

> Why should the checks be able to do anything that standard code 
> cannot do? Why should the checks not have access to context 
> when the actual code will have such access? I think a lot of 
> the trouble you are having probably comes down to compiler bugs 
> and/or missing reasonable enhancement requests.

You've seen the test. It's a lambda outside of unittest. How do 
you propose to write a trait that DOES have access to context? 
Same goes for std.range.isInputRange...

Just to reiterate - I *have* a working implementation of a test 
that works around this problem for testing copy initialization 
specifically. I'm just tired of these workarounds.

```d
struct Container(T)
{
     import core.memory : pureMalloc, pureFree;
     T* storage;
     this(T x)
     {
         // Make known to GC, yadda yadda, skipped for brevity
         import core.lifetime : moveEmplace;
         storage = cast(T*) pureMalloc(T.sizeof);
         moveEmplace(x, *storage);
     }

     this(ref return scope typeof(this) other)
     {
         // This is where I'd use an isNothrowCopyable trait.
         // If T is nothrow-copyable, I'd just allocate and copy 
all things.
         // If it isn't, I'll need an allocation guard and a copy 
algorithm
         // that tracks success and destructs already copied 
things if a given copy fails.
         import core.lifetime : copyEmplace;
         storage = cast(T*) pureMalloc(T.sizeof);
         copyEmplace(*other.storage, *storage);
     }

     ~this() nothrow
     {
         if (storage)
         {
             static if (__traits(hasMember, T, "__xdtor"))
                 storage.__xdtor;
             pureFree(storage);
         }
     }
}

unittest
{
     int dtors;
     struct NestedThatFails
     {
         this(return ref scope typeof(this)) nothrow {}
         ~this() nothrow { ++dtors; }
     }

     {
         NestedThatFails y;
         () nothrow {
             Container!NestedThatFails container = y; // copies 
just fine
             auto copied = container;                 // copies 
just fine
         } ();
     }

     // y, the copy passed to `container`, the value in 
`container`, the value in `copied`,
     // should be 4 dtors (well, ideally 3, but that's only after 
move semantics DIP is implemented).
     assert(dtors == 4);

     // But according to the check, it's not nothrow-copyable!
     static assert(isNothrowCopyable!NestedThatFails);
}

```


More information about the Digitalmars-d mailing list