Thread overview
[Issue 21856] Implicit @safe violation of immutable
Apr 24, 2021
ag0aep6g
Apr 27, 2021
RazvanN
Apr 27, 2021
RazvanN
Apr 28, 2021
anonymous4
April 24, 2021
https://issues.dlang.org/show_bug.cgi?id=21856

ag0aep6g <ag0aep6g@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |safe
                 CC|                            |ag0aep6g@gmail.com

--
April 27, 2021
https://issues.dlang.org/show_bug.cgi?id=21856

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

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

--- Comment #1 from RazvanN <razvan.nitu1305@gmail.com> ---
The error does not have anything to do with `@safe`. The fundamental issue is that the implicit conversion is not signaled appropriately. If `f` is not templated:

immutable(D) f(DA right) {
    D ret = right;
    return ret;
}

The compiler correctly errors: test.d(6): Error: cannot implicitly convert
expression `ret` of type `test.D` to `immutable(D)`

--
April 27, 2021
https://issues.dlang.org/show_bug.cgi?id=21856

--- Comment #2 from RazvanN <razvan.nitu1305@gmail.com> ---
There seems to be a confusion in the compiler with regards to implicit conversions and unique objects. If a pure functions creates a mutable object and then it returns it, then the object is implicitly convertible to immutable because nobody else could possibly modify.

That is why:

immutable(D) f(DA right) pure {
    D ret = right;
    return ret;
}

will compile. The compiler will consider that the function is pure, therefore immutability cannot be broken. I think that this is a bug, since the conversion should work only if the function is strongly pure, not any kind of purity.

But there is also the case of:

immutable(D) f(DA) pure {
    D ret = new D();
    return ret;
}

In the above case, it is fine to convert ret to immutable since nobody can actually modify it.

The safest and most restrictive solution would be to simply allow the conversion only if the function is strongly pure, thus dissalowing the latter case, however, this may break code out there.

--
April 28, 2021
https://issues.dlang.org/show_bug.cgi?id=21856

anonymous4 <dfj1esp02@sneakemail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Hardware|x86_64                      |All
                 OS|Linux                       |All

--- Comment #3 from anonymous4 <dfj1esp02@sneakemail.com> ---
>however, this may break code out there.
That's expected, it's a fix of a flaky type check.

--