[Issue 21511] Uniqueness detection failed in non-template function with delegate parameter
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Tue Dec 29 15:11:04 UTC 2020
https://issues.dlang.org/show_bug.cgi?id=21511
ag0aep6g <ag0aep6g at gmail.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |ag0aep6g at gmail.com
--- Comment #1 from ag0aep6g <ag0aep6g at gmail.com> ---
(In reply to Bolpat from comment #0)
> immutable(int)* g(const scope int* delegate() pure @safe dg) @safe
> {
> return dg(); // error
> }
>
> immutable(int)* h(DG)(const scope DG dg) @safe
> // just to be sure nothing surprising happens:
> if (is(DG == int* delegate() pure @safe))
> {
> return dg(); // okay
> }
>
> The reason why the result of calling the function pointer or delegate are
> valid, is due to uniqueness.[1] Especially weird is the fact that h lowers
> to g after the template parameter is determined (only one option).
[...]
> [1] https://dlang.org/spec/const3.html#creating_immutable_data
There is a significant difference between g and h: g isn't `pure`. h is.
The issue can be summarized like this:
immutable(int)* foo(const scope int* delegate() pure @safe dg) pure @safe
{
immutable int* i = dg(); /* error (line A) */
return dg(); /* no error (line B) */
}
The heart of the problem is that delegates offer a head const mechanism. `dg`
can return a pre-existing mutable int* from its context. It's not guaranteed to
be unique. Example:
class C
{
int x;
int* method() pure @safe { return &x; }
}
void main()
{
auto c = new C;
const int* delegate() dg = &c.method;
int* p = dg(); /* no error; not a unique reference (line C) */
}
Such a `dg()` cannot be allowed to implicitly convert to immutable. The
compiler recognizes that when it rejects line A, but it misses line B.
We can either:
1) disallow line B, or
2) make `const` on delegates transitive, consequently allowing line A and
disallowing line C.
--
More information about the Digitalmars-d-bugs
mailing list