www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 5314] New: Wrong error message: struct within immutable member and postblit function

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5314

           Summary: Wrong error message: struct within immutable member
                    and postblit function
           Product: D
           Version: D2
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: rayerd.wiz gmail.com


--- Comment #0 from Haruki Shigemori <rayerd.wiz gmail.com> 2010-12-03 09:19:34
PST ---
// a.d
struct ID
{
        immutable int value;
        this(this){}
}
void main() {}

$ dmd a.d
Error: this is not mutable
Error: this is not mutable
Error: this is not mutable

- No line number.
- Strange *three* error message.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 03 2010
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5314


Jonathan M Davis <jmdavisProg gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jmdavisProg gmx.com


--- Comment #1 from Jonathan M Davis <jmdavisProg gmx.com> 2010-12-03 11:37:52
PST ---
I've noticed that a lot of errors get printed three times. I have no idea why.
Regardless, the error message is close to correct. The problem is, of course,
that value is immutable, not the this pointer, but the object as a whole is not
mutable, because value is immutable, so saying that this is not mutable is
essentially correct, if somewhat misleading. It needs a better error message,
but the one that's there isn't totally off.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 03 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5314



--- Comment #2 from Haruki Shigemori <rayerd.wiz gmail.com> 2010-12-03 18:44:54
PST ---
(In reply to comment #1)
 I've noticed that a lot of errors get printed three times. I have no idea why.
 Regardless, the error message is close to correct. The problem is, of course,
 that value is immutable, not the this pointer, but the object as a whole is not
 mutable, because value is immutable, so saying that this is not mutable is
 essentially correct, if somewhat misleading. It needs a better error message,
 but the one that's there isn't totally off.
Of course, I know that. I said that the error message has two problems. I didn't say that it is unkindness. However, it makes me happy if the message is more better, because the current message has not class and variable name. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 03 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5314


nfxjfg gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |nfxjfg gmail.com


--- Comment #3 from nfxjfg gmail.com 2010-12-03 19:48:37 PST ---
Are you saying this is not a rejects-valid?

I fail to see why structs with immutable members shouldn't be allowed to have a
postblit function.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 03 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5314



--- Comment #4 from Haruki Shigemori <rayerd.wiz gmail.com> 2010-12-04 00:16:09
PST ---
(In reply to comment #3)
 Are you saying this is not a rejects-valid?
I think that this is maybe a rejects-invalid correctly. Error: this is not mutable Error: this is not mutable Error: this is not mutable However, this error message is bad clearly, because it hasn't line numbers and type/variable names. Of course, this message is strange that it is written by three times. For example, I think that a following sentence is more better. filename.d(4): struct ID has not both postblit and immutable member value
 I fail to see why structs with immutable members shouldn't be allowed to have a
 postblit function.
Uhmmm... I don't discuss the matter because it is other problem. But, we need probably discussion of the problem that you said. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 04 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5314



--- Comment #5 from Haruki Shigemori <rayerd.wiz gmail.com> 2010-12-04 00:18:22
PST ---
- filename.d(4): struct ID has not both postblit and immutable member value
+ filename.d(4): struct ID cannot have both postblit and immutable member value

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 04 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5314



--- Comment #6 from Jonathan M Davis <jmdavisProg gmx.com> 2010-12-06 00:21:15
PST ---
 nfxjfg

This program shows when init, a constructor, the postblit constructor, and
opAssign are used:

import std.stdio;

struct Foo
{
    int a = 7;

    this(int a)
    {
        this.a = a;
        writefln("constructor: %s", this.a);
    }

    this(this)
    {
        writefln("postblit: %s", this.a);
    }

/+
    Foo opAssign(const ref Foo other)
    {
        this.a = other.a;
        writefln("opAssign: %s", this.a);

        return this;
    }
+/
}

void main()
{
    writefln("%s(%s): -------", __FILE__, __LINE__);
    Foo a;
    writefln("%s(%s): -------", __FILE__, __LINE__);
    auto b = Foo(6);
    writefln("%s(%s): -------", __FILE__, __LINE__);
    auto c = a;
    writefln("%s(%s): -------", __FILE__, __LINE__);
    b = c;
    writefln("%s(%s): -------", __FILE__, __LINE__);
}


The output is:

test.d(29): -------
test.d(31): -------
constructor: 6
test.d(33): -------
postblit: 7
test.d(35): -------
postblit: 7
test.d(37): -------


Notice that assignment uses the postblit constructor. If you uncomment
opAssign(), then you get this instead:

test.d(29): -------
test.d(31): -------
constructor: 6
test.d(33): -------
postblit: 7
test.d(35): -------
opAssign: 7
test.d(37): -------


Now, assignment uses opAssign(). The problem with having an immutable member
variable and a postblit constructor is that you cannot reassign that member
variable. That portion of the struct cannot be altered.

If I changed the code to

import std.stdio;

struct Foo
{
    immutable int a;

    this(int a) immutable
    {
        this.a = a;
        writefln("constructor: %s", this.a);
    }

}

void main()
{
    writefln("%s(%s): -------", __FILE__, __LINE__);
    Foo a;
    writefln("%s(%s): -------", __FILE__, __LINE__);
    auto b = Foo(6);
    writefln("%s(%s): -------", __FILE__, __LINE__);
    auto c = a;
    writefln("%s(%s): -------", __FILE__, __LINE__);
    b = c;
    writefln("%s(%s): -------", __FILE__, __LINE__);
}


then it fails to compile, giving the message

test.d(24): Error: variable test.main.b cannot modify immutable


The line b = c is illegal. Now, the line auto c = a is still legal, and you
could arguably allow a postblit constructor which didn't alter the immutable
member variables, but it does get a bit odd. You could arguably even allow for
assignment via opAssign() as long as the immutable member variable isn't
altered, but then it's probably not really copying, which would not be good.

So, I suppose that a postblit could be allowed in a struct with an immutable
member variable, but you couldn't assign to it or do a deep copy or do anything
with it that you'd normally do in a postblit constructor (though whether or not
that's a problem is debatable). But the compiler would have to be smart enough
to realize that having a postblit constructor didn't allow for assignment for
structs with immutable member variables, which may or may not be
straightforward, depending on how the compiler decides that it cannot do an
assignment to a struct with an immutable member variable.

All in all, copying structs with immutable member variables does tend to get a
bit funny. I suppose that a postblit constructor _could_ be allowed, but it is
a bit odd. Assignment certainly can't be allowed, and the postblit constructor
is assignment of a sort, but it could still work as long as it's only used when
constructing a variable. So, I don't know what the correct behavior is.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 06 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5314


kennytm gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ultimatemacfanatic gmail.co
                   |                            |m


--- Comment #7 from kennytm gmail.com 2011-05-01 23:32:49 PDT ---
*** Issue 5917 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 01 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5314


kennytm gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |diagnostic
                 CC|                            |kennytm gmail.com
         OS/Version|Windows                     |All
           Severity|normal                      |critical


--- Comment #8 from kennytm gmail.com 2011-05-01 23:35:22 PDT ---
Raising severity to "Critical" as per bug 5745.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 01 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5314


SomeDude <lovelydear mailmetrash.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |lovelydear mailmetrash.com
           Severity|critical                    |normal


--- Comment #9 from SomeDude <lovelydear mailmetrash.com> 2012-05-04 22:48:45
PDT ---
Reducing criticity to normal, as diagnostic bugs are not critical.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 04 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5314


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug yahoo.com.au
           Severity|normal                      |critical


--- Comment #10 from Don <clugdbug yahoo.com.au> 2012-05-09 13:44:40 PDT ---
(In reply to comment #9)
 Reducing criticity to normal, as diagnostic bugs are not critical.
They're equivalent to compiler segfaults. Worse than any rejects-valid bug. They're nearly always very easy to fix, too. There's no excuse for them. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 09 2012
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5314


Denis Shelomovskij <verylonglogin.reg gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |verylonglogin.reg gmail.com


--- Comment #11 from Denis Shelomovskij <verylonglogin.reg gmail.com>
2012-11-03 15:16:46 MSK ---
Original example compiles fine now but is the issue fixed?

Can somebody familiar with dmd internals check if "%s is not mutable" error
message gives line now:
https://github.com/D-Programming-Language/dmd/blob/master/src/expression.c



Also example from comment #6 with uncommented `opAssign` new writes this:

main.d(29): -------
main.d(31): -------
constructor: 6
main.d(33): -------
postblit: 7
main.d(35): -------
opAssign: 7
postblit: 7              <- added line
main.d(37): -------

The line is added correctly and indicates a fixed compiler bug because

    Foo opAssign(const ref Foo other)

returns by value so a temporary is created.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 03 2012