Instantiation of nested structs should be allowed outside their parent scope

Stanislav Blinov stanislav.blinov at gmail.com
Tue Nov 9 15:30:20 UTC 2021


On Tuesday, 9 November 2021 at 15:07:58 UTC, Timon Gehr wrote:
> On 09.11.21 15:11, Stanislav Blinov wrote:
>> On Tuesday, 9 November 2021 at 09:24:29 UTC, Timon Gehr wrote:
>>> ...
>>>
>>> There is never really a need to instantiate a value of any 
>>> type just to check what it supports.
>> 
>> Yes, there is. isInputRange tries, and fails for some nested 
>> structs (keyword - some).
>
> Fair, sometimes you want to check whether you can declare a 
> value of the given type, though that _should_ fail in case it's 
> not actually possible for the algorithm to do that and get an 
> actually working instance. It's plausible that that check does 
> not actually work correctly for some Phobos functions though, 
> as local instantiation of templates is a bit messy.

The point is it must be possible to test that, and it's not, 
because of some arbitrary artificial limitation. I mean, we can 
freely instantiate null delegates, but we can't instantiate 
nested structs? There's, to me, zero logic in that.

> I see, I guess you actually want this, but it does not work:
>
> enum bool isNothrowCopyable(To, From) = __traits(compiles, 
> (From from)nothrow{ To to=from; });

No, that also tests destruction, of both `from`, because it's D, 
where functions destruct their arguments, and `to`, because it's 
a local :) What I want is this:

```d
template isNothrowCopyable(To, From)
if (is(immutable To == immutable From))
{
     enum bool isNothrowCopyable = is(typeof((ref scope From from) 
nothrow { union U { To to; } U u = U(from); }));
}
```

...but it indeed doesn't work for nested structs. And a thing 
that does "work" has to reimplement compiler's copy semantics, 
including field-by-field blitting, calling constructors and 
postblits, etc.

> What's the use case for checking only this kind of 
> initialization, if you don't need to create new instances of 
> `to`?

? You *do* need to create new instances of `to`. By copying 
existing instances. Any container that wants to support copying 
has to do that, and beyond. I want a test that would also tell me 
if my container needs special handling of exception guarantees, 
or if it can freely do an easy thing and not worry about it: can 
I just copy existing things on element insertion one element 
over, or do I have to do a three step algorithm because copying 
might throw?..
I also want other tests, that would tell me if copying is safe to 
do, if it needs GC, if it's pure... (I *do* have them already, 
but like I said, they're ludicrous, for no other reason than this 
handwaving error message). And as for isInputRange - I haven't 
got a clue if it's even possible to make it work for all nested 
structs unless the compiler stops issuing this error message.


More information about the Digitalmars-d mailing list