www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - ref const array error

reply "jdrewsen" <jdrewsen nospam.com> writes:
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
Jan 18 2012
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
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
Jan 18 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
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 }
Jan 18 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
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.
Jan 18 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/19/2012 03:47 PM, jdrewsen wrote:
 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?

The compiler would catch something in my example, but not the error. The error happens at the call site.
Jan 19 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/19/2012 09:33 PM, jdrewsen wrote:
 On Thursday, 19 January 2012 at 17:00:59 UTC, Timon Gehr wrote:
 On 01/19/2012 03:47 PM, jdrewsen wrote:
 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?

The compiler would catch something in my example, but not the error. The error happens at the call site.

Actually when I think about it using semantic for out/ref that I suggested does not solve the problem at all. I guess the inout thing is the way to go. A pitty that safeDecode only supports the ref const(ubyte)[] version and not ref ubyte[]. I wonder how big of an issue this is for the rest of phobos functions accepting ref parameters. /Jonas

Probably they should eventually be fixed to use inout instead.
Jan 19 2012
prev sibling next sibling parent "jdrewsen" <jdrewsen nospam.com> writes:
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
Jan 18 2012
prev sibling next sibling parent "jdrewsen" <jdrewsen nospam.com> writes:
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?
Jan 18 2012
prev sibling next sibling parent "jdrewsen" <jdrewsen nospam.com> writes:
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?
Jan 19 2012
prev sibling parent "jdrewsen" <jdrewsen nospam.com> writes:
On Thursday, 19 January 2012 at 17:00:59 UTC, Timon Gehr wrote:
 On 01/19/2012 03:47 PM, jdrewsen wrote:
 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?

The compiler would catch something in my example, but not the error. The error happens at the call site.

Actually when I think about it using semantic for out/ref that I suggested does not solve the problem at all. I guess the inout thing is the way to go. A pitty that safeDecode only supports the ref const(ubyte)[] version and not ref ubyte[]. I wonder how big of an issue this is for the rest of phobos functions accepting ref parameters. /Jonas
Jan 19 2012