Possible bug when instantiating template function with nested struct
Stanislav Blinov
stanislav.blinov at gmail.com
Sun Nov 7 18:15:53 UTC 2021
On Sunday, 7 November 2021 at 17:47:45 UTC, Teodor Dutu wrote:
>> void-initialize your to-be-returned array in _d_arrayctor?
>
> Won't this be the same as doing this:
> ```d
> T[] to; // to be returned
> to.length = length;
> ```
> The problem with this approach is that `to` isn't NRVO'd
> because the lowering to `_d_arrayctor` is only done for static
> arrays.
??? No, it will not. The problem in your
```d
Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope
Tarr2 from)
{
Tarr1 to;
// ...
return to;
}
```
is the default initialization. S from the unittest is a nested
struct, and can't be instantiated outside of scope of its parent.
But this should work:
```d
// Obviously concrete implementation would be generic here, and
copy/blit accordingly. This one explicitly calls copy ctor for
illustration purposes only.
Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope
Tarr2 from)
{
// Infer @safe-ty from an actual ctor.
// Note that is is a nuclear option. Ideally you'd check a
trait,
// something like isSafeCopyable!(T1, T2), which would need
to be defined,
// so that no code gets emitted here regardless of build
options
if (false) { T1* a; T2* b; (*a).__ctor(*b); }
return () @trusted
{
Tarr1 to = void;
foreach (i, ref it; to)
it.__ctor(from[i]);
return to;
} ();
}
void main() @safe
{
int counter;
struct Nested
{
this(return ref scope typeof(this) n) { /* ... */ }
~this() { ++counter; }
}
Nested[3] arr1;
Nested[3] arr2 = _d_arrayctor!(typeof(arr1))(arr1);
}
```
> I used `@trusted` because some unittests that used this
> lowering were `@safe`. It was a compile-time workaround.
? It should pass unittests without lying to the compiler, by
correctly inferring @safe-ty.
More information about the Digitalmars-d
mailing list