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