[Issue 20876] DMD gives out not so helpful compile error

d-bugmail at puremagic.com d-bugmail at puremagic.com
Fri May 29 05:14:20 UTC 2020


https://issues.dlang.org/show_bug.cgi?id=20876

RazvanN <razvan.nitu1305 at gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |razvan.nitu1305 at gmail.com

--- Comment #4 from RazvanN <razvan.nitu1305 at gmail.com> ---
(In reply to moonlightsentinel from comment #3)
> Reduced test case:
> 
> struct Array
> {
>     void opSliceAssign(Foo) {}
>     void opSliceAssign(Foo, size_t, size_t) {}
> }
> 
> struct Foo {
>     Bar _bar;
> }
> 
> struct Bar {
>   version (Bug)
>     this(ref Bar) { }
>   else
>     this(Bar) { }
> }
> 
> void main()
> {
>     Foo foo;
>     Array arr;
>     arr[] = foo;
> }

The fundamental problem is that when the compiler sees a struct that has a
field that defines a copy constructor it generates an inout copy construct that
has the form:

this(ref inout(T)) inout;

In this specific situation it creates such a copy constructor for Foo:

this(ref inout(Foo) p) inout
{
    this._bar = p._bar;
}

This generated copy constructor fails to compile because `this._bar = p._bar`
gets rewritten to `this._bar.__copyCtor(p._bar)` and this failst because
`this(ref Bar)` cannot be called with argument types `(ref inout(Bar)) inout`.
Therefore it will be annotated with disable.

When I implemented the copy constructor I initially proposed this scheme having
in mind that if you want to upgrade your postblits to copy constructors, then
you can simply replace `this(this)` with `this(ref inout typeof(this) p)
inout`. That way the generation scheme for postblits would work kind of the
same and the code would not be affected. However, pondering upon it some more I
thought of a superior generation scheme [1]. The latter would make this error
go away and the code would compile, however Walter opposed it so now we are
stuck with inout constructors.

So, to conclude, by the current language rules the error is correct.

The fix in this situation would be to annotate the copy constructor of Bar with
`inout`: this(ref inout(Bar)) inout . That will make the code to compile.

But I agree that the error could be improved.

[1]
https://github.com/dlang/DIPs/pull/129/commits/7815bc3fc49dd9f1a2195f871f3f6afe6c9d6c8b#diff-7f9578c76cc7367ecc56acfce679fc4bR675

--


More information about the Digitalmars-d-bugs mailing list