digitalmars.D.bugs - [Issue 6695] New: immutable not inherited by members
- d-bugmail puremagic.com (29/29) Sep 19 2011 http://d.puremagic.com/issues/show_bug.cgi?id=6695
- d-bugmail puremagic.com (44/44) Sep 20 2011 http://d.puremagic.com/issues/show_bug.cgi?id=6695
- d-bugmail puremagic.com (40/40) Sep 20 2011 http://d.puremagic.com/issues/show_bug.cgi?id=6695
- d-bugmail puremagic.com (37/37) Sep 20 2011 http://d.puremagic.com/issues/show_bug.cgi?id=6695
- d-bugmail puremagic.com (9/12) Sep 20 2011 http://d.puremagic.com/issues/show_bug.cgi?id=6695
- d-bugmail puremagic.com (20/26) Sep 20 2011 http://d.puremagic.com/issues/show_bug.cgi?id=6695
- d-bugmail puremagic.com (11/29) Sep 20 2011 http://d.puremagic.com/issues/show_bug.cgi?id=6695
- d-bugmail puremagic.com (39/65) Sep 20 2011 http://d.puremagic.com/issues/show_bug.cgi?id=6695
- d-bugmail puremagic.com (37/49) Sep 20 2011 http://d.puremagic.com/issues/show_bug.cgi?id=6695
- d-bugmail puremagic.com (8/64) Sep 20 2011 http://d.puremagic.com/issues/show_bug.cgi?id=6695
- d-bugmail puremagic.com (16/16) Oct 05 2011 http://d.puremagic.com/issues/show_bug.cgi?id=6695
- d-bugmail puremagic.com (10/10) Oct 06 2011 http://d.puremagic.com/issues/show_bug.cgi?id=6695
- d-bugmail puremagic.com (13/13) Oct 06 2011 http://d.puremagic.com/issues/show_bug.cgi?id=6695
http://d.puremagic.com/issues/show_bug.cgi?id=6695 Summary: immutable not inherited by members Product: D Version: unspecified Platform: All OS/Version: All Status: NEW Severity: major Priority: P2 Component: DMD AssignedTo: nobody puremagic.com ReportedBy: luka8088 owave.net import std.stdio; immutable struct a { b b1; } struct b { void c () immutable { writeln(typeid(typeof(this))); // b instead of immutable(b) } } void main () { a a1; a1.b1.c(); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 19 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6695 Steven Schveighoffer <schveiguy yahoo.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |schveiguy yahoo.com Version|unspecified |D2 Summary|immutable not inherited by |typeof(this) does not take |members |into account | |const/immutable attributes | |inside member functions 05:53:59 PDT --- This is only a problem with the expression typeof(this), the real reference 'this' actually *is* immutable: simplified example: import std.stdio; struct b { void c () immutable { writeln(typeid(typeof(this))); // b auto x = this; writeln(typeid(typeof(x))); // immutable(b) } } void main() { immutable b b1; b1.c(); } However, if you tried to change a member of b, you will get a compiler error. So the type of the this reference inside c() is not simply b, it really is immutable(b). However, typeof(this) is a special expression that the compiler replaces with the actual type of the struct (i.e. struct b). This is so it can be used in static functions and at a declaration level. See the special cases here: http://www.d-programming-language.org/declaration.html#Typeof However, I think it is extremely unintuitive to make that happen inside a member function as well. I'm not sure if this is an enhancement, it's not exactly clear from the spec that typeof(this) should still be a special case *inside* a member function. It says it should be the same as if it were inside a member function, it doesn't say *what kind* of member function. At the very least, this is a doc bug. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 20 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6695 The actual problem is: import std.stdio; immutable struct a { b b1; } struct b { /* void c () { } case 1 => Error: function b.c () is not callable using argument types () immutable void c () immutable { } case 2 => Error: function b.c () immutable is not callable using argument types () */ void c () { } } void main () { a a1; b b1; a1.b1.c(); // case 1 b1.c(); // case 2 } Lets say there is a struct b that can be independent and is mutable. On the other hand we have struct a that has b immutable, by some reason immutable is not inherited by void c () { }, so by trying to call a1.b1.c(); compiler throws Error: function b.c () is not callable using argument types () immutable I also tried a work-around by making void c () immutable { }, but then independent usage of b throws Error: function b.c () immutable is not callable using argument types () The reason for trying typeof(this) is I was trying to make two functions: void c () if (is(typeof(this) == b)) { } void c () if (is(typeof(this) == immutable(b))) immutable { } but since typeof(this) does not indicate immutable I found no work-around. Until this is resolved, is there any work-around for this situation... or am I doing something wrong ? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 20 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6695 08:47:22 PDT --- void c() const {} This should work, as mutable and const implicitly cast to immutable. Two other things (even though the above is the *right* solution to your problem): 1. You can overload c, you don't need to use a template 2. You *can* get the exact type called with by using a this template parameter: import std.stdio; struct b { void c(this T)() const { writeln(typeid(T)); } } void main() { immutable b b1; b b2; b1.c(); b2.c(); } output: immutable(testimmutable.b) testimmutable.b But please note, the struct a has nothing to do with these issues, it's just simply a way you have declared an immutable b (which you can easily do on the stack). Declaring an immutable struct is the same as applying immutable to all the members. Declaring a local immutable variable is the same thing. Also note that in your attempt to use if constraints, you must use templates (I'm sure you would have gotten error messages, so I think this is a simple copy-paste omission) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 20 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6695 08:48:52 PDT ---void c() const {} This should work, as mutable and const implicitly cast to immutable.Oh my, that was completely off. Should have read: This should work, as mutable and immutable implicitly cast to const. Sorry... -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 20 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6695void c() const {} This should work, as mutable and const implicitly cast to immutable.yes, it works, thx !Declaring an immutable struct is the same as applying immutable to all the members. Declaring a local immutable variable is the same thing.so this is a bug or not ... ? // Error: function b.c () is not callable using argument types () immutable import std.stdio; immutable struct a { b b1; } struct b { void c () { } } void main () { a a1; a1.b1.c(); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 20 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6695 10:26:54 PDT ---so this is a bug or not ... ? // Error: function b.c () is not callable using argument types () immutable import std.stdio; immutable struct a { b b1; } struct b { void c () { } } void main () { a a1; a1.b1.c(); }Not a bug. Inside the c function, 'this' is mutable, and you are trying to pass an immutable struct as the 'this' parameter. Immutable cannot implicitly cast to mutable, so it fails to compile. You should read up on the spec documentation about const and immutable, it will help to understand it. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 20 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6695I agree that maybe this is not a bug, but I don't agree with the explanation ... Documentation says "Both immutable and const are transitive, which means that any data reachable through an immutable reference is also immutable, and likewise for const." So in this example: import std.stdio; immutable struct a { b b1; } struct b { immutable void c () { } void d () { } immutable int e ; int f ; } void main () { a a1; b b1; writeln(" b1.c ", typeid(typeof(b1.c))); // immutable(void()) writeln(" b1.d ", typeid(typeof(b1.d))); // void() writeln(" b1.e ", typeid(typeof(b1.e))); // immutable(int) writeln(" b1.f ", typeid(typeof(b1.f))); // int writeln("a1.b1.c ", typeid(typeof(a1.b1.c))); // immutable(void()) writeln("a1.b1.d ", typeid(typeof(a1.b1.d))); // void() writeln("a1.b1.e ", typeid(typeof(a1.b1.e))); // immutable(int) writeln("a1.b1.f ", typeid(typeof(a1.b1.f))); // immutable(int) } From the documentation, both typeid(typeof(a1.b1.d)) and typeid(typeof(a1.b1.f)) should be either mutable or immutable, right ? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------so this is a bug or not ... ? // Error: function b.c () is not callable using argument types () immutable import std.stdio; immutable struct a { b b1; } struct b { void c () { } } void main () { a a1; a1.b1.c(); }Not a bug. Inside the c function, 'this' is mutable, and you are trying to pass an immutable struct as the 'this' parameter. Immutable cannot implicitly cast to mutable, so it fails to compile. You should read up on the spec documentation about const and immutable, it will help to understand it.
Sep 20 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6695 11:42:19 PDT ---I agree that maybe this is not a bug, but I don't agree with the explanation ... Documentation says "Both immutable and const are transitive, which means that any data reachable through an immutable reference is also immutable, and likewise for const."Note the key element here is *data*, not *functions*.So in this example:[snip]From the documentation, both typeid(typeof(a1.b1.d)) and typeid(typeof(a1.b1.f)) should be either mutable or immutable, right ?typeid(typeof(a1.b1.d)) is a method, not a piece of data. In fact, when you say typeof(a1.b1.d), you might as well have written typeof(b.d). There is a confusing concept to grasp, and it's made harder because of the terminology. An immutable function is not actually immutable. An immutable function is a member function that *can be called* on an immutable instance of the struct/class. The immutable modifier only affects the 'this' pointer, even though it seems like it's applied to the entire function. Remember that all member functions have a hidden this pointer? If we were forced to write them out, then this: struct S { void foo () immutable {} void foo2() const {} void foo3() {} } becomes this: struct S { void foo (ref immutable(S) this) {} void foo2(ref const(S) this) {} void foo3(ref S this) {} } Now you can see why its clear you cannot call for instance foo with a non-immutable instance of S. The reason the modifiers are applied to the function is because there's no parameter for them to cling to -- the parameter is hidden. If you want to discuss this more, I think the d.learn newsgroup is probably best, or you can email me directly. I'd be happy to answer any questions on it. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 20 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6695OK, I understand it now, you are right, thank you very much for detailed explanation ! -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------I agree that maybe this is not a bug, but I don't agree with the explanation ... Documentation says "Both immutable and const are transitive, which means that any data reachable through an immutable reference is also immutable, and likewise for const."Note the key element here is *data*, not *functions*.So in this example:[snip]From the documentation, both typeid(typeof(a1.b1.d)) and typeid(typeof(a1.b1.f)) should be either mutable or immutable, right ?typeid(typeof(a1.b1.d)) is a method, not a piece of data. In fact, when you say typeof(a1.b1.d), you might as well have written typeof(b.d). There is a confusing concept to grasp, and it's made harder because of the terminology. An immutable function is not actually immutable. An immutable function is a member function that *can be called* on an immutable instance of the struct/class. The immutable modifier only affects the 'this' pointer, even though it seems like it's applied to the entire function. Remember that all member functions have a hidden this pointer? If we were forced to write them out, then this: struct S { void foo () immutable {} void foo2() const {} void foo3() {} } becomes this: struct S { void foo (ref immutable(S) this) {} void foo2(ref const(S) this) {} void foo3(ref S this) {} } Now you can see why its clear you cannot call for instance foo with a non-immutable instance of S. The reason the modifiers are applied to the function is because there's no parameter for them to cling to -- the parameter is hidden. If you want to discuss this more, I think the d.learn newsgroup is probably best, or you can email me directly. I'd be happy to answer any questions on it.
Sep 20 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6695 --- This issue is not limited only typeof(this). struct S { int x; void f() immutable { static assert(is(typeof(x) == immutable(int))); // fails! static assert(is(typeof(x) == int)); // pass, but it is fake } } Because typeof(x) inside immutable member function f is translated to typeof(this.x), and `this` is specially typed as S, then typeof returns int. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 05 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6695 Kenji Hara <k.hara.pg gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |patch --- https://github.com/D-Programming-Language/dmd/pull/434 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 06 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6695 Walter Bright <bugzilla digitalmars.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED CC| |bugzilla digitalmars.com Resolution| |FIXED 02:25:32 PDT --- https://github.com/D-Programming-Language/dmd/commit/48ad063f127d3b150f4f1ed5cb4b27ff18d9b6fe https://github.com/D-Programming-Language/dmd/commit/451dbb73e356e3cf530cfc11e1b5094bc2b823af -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 06 2011