On Sun, Dec 4, 2011 at 2:46 PM, Andrew Wiley <wiley.andre...@gmail.com> wrote: > On Sun, Dec 4, 2011 at 1:42 AM, Jonathan M Davis <jmdavisp...@gmx.com> wrote: >> On Sunday, December 04, 2011 01:24:02 Andrew Wiley wrote: >>> This should work, right? I'm not just going crazy or something? >>> >>> import std.concurrency; >>> import std.stdio; >>> >>> class Bob { >>> } >>> >>> void main() { >>> auto tid = spawn(&b); >>> tid.send(new immutable(Bob)()); >>> } >>> >>> void b() { >>> receive( >>> (immutable(Bob) b) { >>> writeln("got it"); >>> } >>> ); >>> } >>> >>> >>> I'm getting this from both GDC (trunk) and DMD (2.056 and trunk - I >>> can't seem to get 2.055 to run): >>> core.exception.AssertError@/usr/include/d/std/variant.d(286): immutable(Bob) >>> >>> Seems like some type conversion isn't working properly and variant is >>> flagging immutable types as not assignable? >> >> Well, that particular assertion seems to be because of the immutability. It >> seems that Variant can't handle it - the comment with it being >> >> // type is not assignable >> >> But I'd have to go digging to see why on earth this is failing (and that's >> assuming that it's not a compiler bug, since then it would be completely out >> of my league). It _looks_ like it should work. >> >> - Jonathan M Davis > > Actually, it looks like I am going crazy. I went back to dmd 2.052 > (and every version in between), and this doesn't seem to have ever > worked. > However, not allowing message passing with immutable messages > eliminates one of the main use cases for immutable. I'll see if I can > find a workaround. > > The actual issue is that once Variant finds a matching type, it tries > to assign `immutable(Bob) = immutable(Bob)` , which is illegal. > However, all it needs to do is assign a *reference* to an immutable > object. Unfortunately, we don't support that. > Incidentally, this makes a compelling argument for something like > immutable(Object) ref.
So it looks like right now, message passing is copying objects, which seems very bad. Check this out: -------- import std.stdio; import std.concurrency; class Bob { } void main() { auto tid = spawn(&func); auto bob = new shared(Bob)(); writeln("bob is currently at ", cast(void*)(&bob)); tid.send(bob); } void func() { receive( (shared(Bob) bob) { writeln("now it's at: ", cast(void*)(&bob)); } ); } -------- This results in output like: -------- bob is currently at 18FE44 now it's at: 29DFE30 -------- Which seems to imply that my object was copied, which clearly was not what I wanted. If I put the reference into an array, it copies the array struct and you wind up with a reference to the same object, but if I pass in a reference to a shared object, it copies the object. This doesn't seem to be the correct way to handle reference types to me.