Bug 9230 – Incorrect implicit immutable conversion occurs in pure function
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-12-27T19:02:00Z
Last change time
2013-01-16T06:11:52Z
Keywords
accepts-invalid, pull
Assigned to
nobody
Creator
k.hara.pg
Comments
Comment #0 by k.hara.pg — 2012-12-27T19:02:24Z
From: http://d.puremagic.com/issues/show_bug.cgi?id=6553
In git head, following code compiles without errors, and asserts in runtime.
string foo(in char[] s) pure {
return s; // conversion from const(char[]) to string
}
void main() {
char[] buf = ['a'];
immutable str = foo(buf);
assert(str[0] == 'a');
buf[0] = 'b';
assert(str[0] == 'a'); // fails!?
}
There is a problem on the return statement in foo. Complier deduces foo to a strong purity function, but its parameter s might refer outer mutable state, so the conversion const(char[]) to string should not be applied.
This is an implementation bug of issue 5081.
https://github.com/D-Programming-Language/dmd/commit/99e0f21d2a7a19b655d97fa08394a3bc623f10a0https://github.com/D-Programming-Language/dmd/commit/99e0f21d2a7a19b655d97fa08394a3bc623f10a0#L3R3524
The implicit immutable conversion on return statement is valid only if the strong purity function has *no parameters*.
This bug has appeared by the purity calculation improvement by issue 8408.
Comment #1 by k.hara.pg — 2012-12-27T20:19:47Z
(In reply to comment #0)
> The implicit immutable conversion on return statement is valid only if the
> strong purity function has *no parameters*.
...No, this is incorrect. I found a disproof.
Correct requirement is:
"If all parameters have no mutable indirections, implicit immutable conversion on return statement is allowed."
For example:
immutable(int[]) foo(int n) { return new int[](n); }
immutable(int[]) bar(immutable int[] arr) { return new int[](arr.length); }
void main() {
immutable a = foo(10);
immutable b = bar([1,2]);
}
Both foo and bar should be allowed.
(In reply to comment #0)
> From: http://d.puremagic.com/issues/show_bug.cgi?id=6553
>
> In git head, following code compiles without errors, and asserts in runtime.
>
> string foo(in char[] s) pure {
> return s; // conversion from const(char[]) to string
> }
> void main() {
> char[] buf = ['a'];
> immutable str = foo(buf);
> assert(str[0] == 'a');
> buf[0] = 'b';
> assert(str[0] == 'a'); // fails!?
> }
>
> There is a problem on the return statement in foo. Complier deduces foo to a
> strong purity function, but its parameter s might refer outer mutable state, so
> the conversion const(char[]) to string should not be applied.
>
> This is an implementation bug of issue 5081.
>
> This bug has appeared by the purity calculation improvement by issue 8408.
The patch for issue 5081 was corrent, the problem is that the definition of strong purity has been changed since then.
(In reply to comment #1)
> (In reply to comment #0)
> > The implicit immutable conversion on return statement is valid only if the
> > strong purity function has *no parameters*.
>
> ...No, this is incorrect. I found a disproof.
>
> Correct requirement is:
> "If all parameters have no mutable indirections, implicit immutable conversion
> on return statement is allowed."
>
This is the old definition of strong purity.
Comment #4 by yebblies — 2012-12-27T21:48:43Z
(In reply to comment #1)
> Correct requirement is:
> "If all parameters have no mutable indirections, implicit immutable conversion
> on return statement is allowed."
>
Maybe it should say 'no non-immutable indirections'?
Comment #5 by k.hara.pg — 2012-12-27T23:15:58Z
(In reply to comment #3)
> The patch for issue 5081 was corrent, the problem is that the definition of
> strong purity has been changed since then.
> This is the old definition of strong purity.
Hmm...interesting, and it might be true. I have thought that "the old definition" was a conservative rule, and did proposed issue 8408 to improve it. But, based on your talk, I have *changed* the definition of strong purity more strictly.
I withdraw the claim that it was an implementation bug.
(In reply to comment #4)
> (In reply to comment #1)
> > Correct requirement is:
> > "If all parameters have no mutable indirections, implicit immutable conversion
> > on return statement is allowed."
>
> Maybe it should say 'no non-immutable indirections'?
Yes, it is more exact explanation.
(I sometimes called the const qualified indirections to "mutable indirection" - e.g. const(int)[]. Because it is an opposite of "immutable indirection".)
Comment #6 by github-bugzilla — 2012-12-28T02:11:30Z