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