On Wednesday, 18 January 2012 at 23:09:56 UTC, Timon Gehr wrote:
On 01/18/2012 10:12 PM, jdrewsen wrote:
On Wednesday, 18 January 2012 at 20:13:04 UTC, Timon Gehr
wrote:
On 01/18/2012 08:59 PM, jdrewsen wrote:
On Wednesday, 18 January 2012 at 19:43:52 UTC, Timon Gehr
wrote:
On 01/18/2012 08:31 PM, jdrewsen wrote:
Recently the encoding.safeDecode stopped working for some
of my
existing
code. This example outlines the issue:
import std.encoding;
void main(string[] args) {
auto e = EncodingScheme.create("utf-8");
auto a = new byte[100];
e.safeDecode(a);
}
Results in:
Error: function std.encoding.EncodingScheme.safeDecode (ref
const(ubyte)[] s) const is not callable using argument
types (byte[])
Isn't this an error in the compiler?
/Jonas
No, this is a bugfix. The operation is unsound:
immutable(ubyte)[] foo(ref const(ubyte)[] s){
auto r = new immutable(ubyte)[1];
s = r;
return r;
}
void main() {
ubyte[] x;
immutable(ubyte)[] y = foo(x);
static assert(is(typeof(y[0])==immutable));
auto oldy0 = y[0];
x[0]=oldy0+1;
assert(oldy0 == y[0]); // fail
}
The functionality is not going away; You will be able to
use inout for
the same purpose once my enhancement request gets
implemented:
http://d.puremagic.com/issues/show_bug.cgi?id=7105
Wouldn't a nicer solution be to let the compiler ensure that
an immutable array cannot escape through a ref const array
parameter?
/Jonas
That would not suffice.
ubyte[] foo(ref const(ubyte)[] s){
auto r = new ubyte[1];
s = r;
return r;
}
void main() {
immutable(ubyte)[] x;
ubyte[] y = foo(x);
static assert(is(typeof(x[0])==immutable));
auto oldx0 = x[0];
y[0]=oldx0+1;
assert(oldx0 == x[0]); // fail
}
In the example foo is actually using the ref s parameter as an
out
parameter. The compiler could catch that you're doing this and
show an
error.
This would force you to let foo look like:
ubyte[] foo(out const(ubyte)[] s);
Wouldn't that fix it?
If it is ref or out is irrelevant for the example, so how would
this fix anything? The compiler could, in principle, treat
const similarly to inout (just without the context sensitivity
and parameter matching etc) for 'ref' parameters and do all the
type checking at the call site. However, that would then
restrict what the callee can do and introduce a strange special
case. inout is the way to go.
But in the example you're using s as an out parameter and that
should trigger the error I got originally of course. But if ref
parameters were disallowed to be used as out parameters the
compiler would catch the error in your example wouldn't it?