Bug 14155 – [REG2.066] A defect in DIP29: the return value of some pure functions cannot be unique pointer
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2015-02-09T09:49:00Z
Last change time
2015-02-21T09:11:14Z
Keywords
accepts-invalid, pull, spec
Assigned to
nobody
Creator
k.hara.pg
Comments
Comment #0 by k.hara.pg — 2015-02-09T09:49:30Z
DIP29 extended language to support uniqueness. However, the definition contains a problem.
http://wiki.dlang.org/DIP29
> CallExpression
> if function is pure, then result is the and'ing of all the arguments to the function
By that, in some cases the implicit conversion may introduce type system breaking.
Example:
immutable int g;
// runtime initialization, to prevent constfold on all 'g' access
static this() { g = 1; }
// foo has constant purity, and
// its argument may appear in return value.
// (== the return value is not isolated from the arguments.)
// Any pure function can access immutable global data.
// Therefore returning &g by using const(int)* is completely valid.
const(int)* foo(const(int)* p) pure { return &g; }
void main()
{
assert(g == 1);
// By DIP29 definition, NewExpression is unique pointer.
// Therefore the call of foo is deduced to unique and
// it's implicitly converted to int*.
int* p = foo(new int());
*p = 2;
assert(g == 2); // blam!
}
DIP29 was implemented in 2.066, so it's a regression.
Comment #1 by k.hara.pg — 2015-02-09T13:19:29Z
Related case with NewExpression.
immutable int g;
static this() { g = 1; }
class C
{
int* p;
this(int) immutable pure { p = &g; }
}
void main()
{
C c = new immutable C(1);
*c.p = 2;
assert(g == 2); // blam!
}