Jump to page: 1 24  
Page
Thread overview
immutable bug?
Jan 11, 2014
Manu
Jan 11, 2014
John Colvin
Jan 11, 2014
Maxim Fomin
Jan 11, 2014
Adam D. Ruppe
Jan 11, 2014
Maxim Fomin
Jan 11, 2014
Timon Gehr
Jan 12, 2014
Peter Alexander
Jan 12, 2014
Manu
Jan 12, 2014
David Nadlinger
Jan 12, 2014
Peter Alexander
Jan 12, 2014
Manu
Jan 12, 2014
Peter Alexander
Jan 12, 2014
Daniel Murphy
Jan 12, 2014
David Nadlinger
Jan 13, 2014
David Nadlinger
Jan 12, 2014
Timon Gehr
Jan 12, 2014
Timon Gehr
Jan 12, 2014
Manu
Jan 12, 2014
Timon Gehr
Jan 12, 2014
Kagamin
Jan 11, 2014
John Colvin
Jan 11, 2014
anonymous
Jan 12, 2014
Johnny Walking
Jan 12, 2014
Timon Gehr
Jan 13, 2014
Manu
Jan 13, 2014
Rikki Cattermole
Jan 13, 2014
Brad Roberts
Jan 13, 2014
Rikki Cattermole
Jan 13, 2014
Guido Kollerie
Jan 13, 2014
Manu
January 11, 2014
I just managed to assign a const(char)[] to a string... caused crashes when the original memory disappeared.

inout(char)[] todstr(inout(char)* cstr) pure nothrow
{
return cstr ? cstr[0 .. std.c.string.strlen(cstr)] : cstr[0 .. 0];
}

struct Data
{
char buffer[256] = void;
@property const(char)[] filename() const pure nothrow { return
todstr(buffer.ptr); }
}

struct MyThing
{
private this(in Data* p)
{
filename = p.filename; // *** Uh oh! assigned a const(char)[] @property to
a string! ***
}

string filename;
}

Surely that assignment shouldn't be legal? Shouldn't I need to idup?


January 11, 2014
On Saturday, 11 January 2014 at 18:29:36 UTC, Manu wrote:
> I just managed to assign a const(char)[] to a string... caused crashes when
> the original memory disappeared.
>
> inout(char)[] todstr(inout(char)* cstr) pure nothrow
> {
> return cstr ? cstr[0 .. std.c.string.strlen(cstr)] : cstr[0 .. 0];
> }
>
> struct Data
> {
> char buffer[256] = void;
> @property const(char)[] filename() const pure nothrow { return
> todstr(buffer.ptr); }
> }
>
> struct MyThing
> {
> private this(in Data* p)
> {
> filename = p.filename; // *** Uh oh! assigned a const(char)[] @property to
> a string! ***
> }
>
> string filename;
> }
>
> Surely that assignment shouldn't be legal? Shouldn't I need to idup?

I don't know about the details of what is/isn't legal here, but the only reason the compiler accepts it is because filename is marked as pure.
January 11, 2014
On Saturday, 11 January 2014 at 18:43:39 UTC, John Colvin wrote:
>
> I don't know about the details of what is/isn't legal here, but the only reason the compiler accepts it is because filename is marked as pure.

It is legal exactly because function is marked as pure. Result of pure function is implicitly convertible to immutable.
January 11, 2014
On Saturday, 11 January 2014 at 18:48:15 UTC, Maxim Fomin wrote:
> It is legal exactly because function is marked as pure. Result of pure function is implicitly convertible to immutable.

It shouldn't be here though... the reason it is implicitly convertable is that pure means the result is unique. But, with the hidden this pointer having a reference to the data as well, it obviously is not unique. I think the compiler should catch this; i'd call it a bug.
January 11, 2014
On Saturday, 11 January 2014 at 18:48:15 UTC, Maxim Fomin wrote:
> On Saturday, 11 January 2014 at 18:43:39 UTC, John Colvin wrote:
>>
>> I don't know about the details of what is/isn't legal here, but the only reason the compiler accepts it is because filename is marked as pure.
>
> It is legal exactly because function is marked as pure. Result of pure function is implicitly convertible to immutable.

I had heard this mentioned before; is it true in all cases?
Even when the function returns a reference to external data?
January 11, 2014
On Saturday, 11 January 2014 at 18:29:36 UTC, Manu wrote:
> I just managed to assign a const(char)[] to a string... caused crashes when
> the original memory disappeared.
>
> inout(char)[] todstr(inout(char)* cstr) pure nothrow
> {
> return cstr ? cstr[0 .. std.c.string.strlen(cstr)] : cstr[0 .. 0];
> }
>
> struct Data
> {
> char buffer[256] = void;
> @property const(char)[] filename() const pure nothrow { return
> todstr(buffer.ptr); }
> }
>
> struct MyThing
> {
> private this(in Data* p)
> {
> filename = p.filename; // *** Uh oh! assigned a const(char)[] @property to
> a string! ***
> }
>
> string filename;
> }
>
> Surely that assignment shouldn't be legal? Shouldn't I need to idup?

Simplified:

const(char)[] slice(ref const char[1] c) pure nothrow
{
        return c[];
}

void main()
{
        char[1] m = ".";

        immutable i = slice(m); // should not compile
        assert(i == ".");

        m = "!"; // uh-oh
        assert(i == "."); // fails
}
January 11, 2014
On Saturday, 11 January 2014 at 18:52:39 UTC, Adam D. Ruppe wrote:
> On Saturday, 11 January 2014 at 18:48:15 UTC, Maxim Fomin wrote:
>> It is legal exactly because function is marked as pure. Result of pure function is implicitly convertible to immutable.
>
> It shouldn't be here though... the reason it is implicitly convertable is that pure means the result is unique. But, with the hidden this pointer having a reference to the data as well, it obviously is not unique. I think the compiler should catch this; i'd call it a bug.

Creating undefined behavior is not a sufficient reason to be a bug.

Changelog mentions example with pure struct constructors which provide value implicitly castable to immutable. So, strictly speaking current behavior is conforming to spec.

You can still argue that the example does not address the issue with 'this' parameter, so code should be rejected (which should happen from safity aspect). I think this case was not considered when 'unique expression' was introduced, so it is yet another hole in type system (to be more precise, bug is in spec-language, not compiler).
January 11, 2014
On 01/11/2014 08:16 PM, Maxim Fomin wrote:
> On Saturday, 11 January 2014 at 18:52:39 UTC, Adam D. Ruppe wrote:
>> On Saturday, 11 January 2014 at 18:48:15 UTC, Maxim Fomin wrote:
>>> It is legal exactly because function is marked as pure. Result of
>>> pure function is implicitly convertible to immutable.
>>
>> It shouldn't be here though... the reason it is implicitly convertable
>> is that pure means the result is unique. But, with the hidden this
>> pointer having a reference to the data as well, it obviously is not
>> unique. I think the compiler should catch this; i'd call it a bug.
>
> Creating undefined behavior is not a sufficient reason to be a bug.
> ...

Add a @safe annotation and it is.

> Changelog mentions example with pure struct constructors which provide
> value implicitly castable to immutable. So, strictly speaking current
> behavior is conforming to spec.
>
> You can still argue that the example does not address the issue with
> 'this' parameter, so code should be rejected (which should happen from
> safity aspect). I think this case was not considered when 'unique
> expression' was introduced, so it is yet another hole in type system (to
> be more precise, bug is in spec-language, not compiler).

It is an implementation bug. Implicit conversion to immutable is only supposed to work for strongly pure functions.
January 12, 2014
On Saturday, 11 January 2014 at 21:16:55 UTC, Timon Gehr wrote:
> It is an implementation bug. Implicit conversion to immutable is only supposed to work for strongly pure functions.

Can someone that knows all the details of the purity strength semantic differences please open a PR to get some documentation in the spec?

I've updated this bug with a comment: https://d.puremagic.com/issues/show_bug.cgi?id=7456
January 12, 2014
On 12 January 2014 04:52, Adam D. Ruppe <destructionator@gmail.com> wrote:

> On Saturday, 11 January 2014 at 18:48:15 UTC, Maxim Fomin wrote:
>
>> It is legal exactly because function is marked as pure. Result of pure function is implicitly convertible to immutable.
>>
>
> It shouldn't be here though... the reason it is implicitly convertable is that pure means the result is unique.


Can you explain how this is true? I can't see anything about the concept of
purity that suggests the result should be unique...
Pure just means given the same inputs, it will produce the same outputs;
external state can't affect the calculation.

In this case, that's perfectly true. 'this' is just a function arg; it's
not mutated by external state (or at all), given the same this, it will
return the same thing every time.
That doesn't make any claims about what 'this' is though, and whether it's
immutable or 'unique' or whatever. It just promises to transform it in an
identical way given the same inputs...
?

But, with the hidden this pointer having a reference to the data as well,
> it obviously is not unique. I think the compiler should catch this; i'd call it a bug.
>


« First   ‹ Prev
1 2 3 4