On Thursday, 12 August 2021 at 15:39:40 UTC, Learner wrote:

It is not clear to me why the inout generated copy constructor of the B structure is not able to copy the A structure.

    struct A
    {
        int[] data;

this(ref return scope A rhs) { /* body */ } this(ref return scope const A rhs) const { /* body */} this(ref return scope immutable A rhs) immutable { /* body */}
    }

    struct B
    {
// default generated copy constructor, by section 14.15.6.2
        this(ref return scope inout(B) src) inout
        {
foreach (i, ref inout field; src.tupleof) this.tupleof[i] = field;
        }
    }

Can point me to a code example of when the D generated copy constructor fails to copy A, and why?

You have forgotten to add a member variable of type `A` to your `B` struct. If you add one, you will see the following error message:

```
onlineapp.d(18): Error: none of the overloads of `__ctor` are callable using a `inout` object, candidates are:
onlineapp.d(5):        `onlineapp.A.this(return ref scope A rhs)`
onlineapp.d(6): `onlineapp.A.this(return ref scope const(A) rhs)` onlineapp.d(7): `onlineapp.A.this(return ref scope immutable(A) rhs)`
```

(Full example: https://run.dlang.io/is/9BrpZj)

Essentially, you cannot use a mutable, `const`, or `immutable` copy constructor to copy an `inout` object, only an `inout` copy constructor.

The reason for this is a bit subtle. Normally, `inout` can convert to `const`, so you might expect that the `const` copy constructor could be used to construct a copy of an `inout` object. However, copy constructors take their arguments by `ref`, and implicit conversions are not allowed for arguments passed to `ref` parameters. (I cannot find a citation in the spec for this, but you can verify it yourself.)

Here's a simplified example that gives the same error:

```d
void f(inout(int)[] a)
{
    g(a);
}

void g(ref int[] a) {}
void g(ref const(int)[] a) {}
void g(ref immutable(int)[] a) {}
```

Reply via email to