On Thursday, October 31, 2013 15:03:26 Daniel Davidson wrote: > Given this code: > > import plus.tvm.rate_curve; > struct T { > RateCurve m; > } > struct S { > const(T) rc; > } > > I get this error: Error: mutable method > plus.models.dossier.__unittestL42_1.T.__fieldPostBlit is not > callable using a const object > > Is this fundamentally incorrect? I abandoned immutable in hopes > that const would be more manageable and so far it has. But these > types of issues still crop up and stop me in my tracks. > > What are the requirements on RateCurve and T for this to work?
const and postblit fundamentally don't mix, because for it to work, you have to violate the type system. With postblits, the struct gets memcpied and then the postblit constructor has the chance to mutate the resulting object to make the pieces different that need to be different. However, to do that mutation when the object is const would mean mutating a const object which violates the type system. What we really need is copy constructors, but they haven't been added yet. At one point, Andrei was saying that he and Walter had a solution, but he didn't elaborate on it. I assume that it involved introducing copy constructors, but I don't know, and this issue has not yet been resolved. Now, in your particular code example, you don't define postblit constructor, but my guess would be that RateCurve defines one, making it so that a postblit constructor is generated for T which uses the one for RateCurve, and the S gets one which uses T's. And because const doesn't work with postblit constructors, S becomes uncopyable, and if there's any code that requires that a copy be made, then it'll fail to compile (I'm not sure whether the fact that it's uncopyable will result in an error if no attempts to copy it are made, but you'll definitely get an error if an attempt to copy is made). Hopefully, this problem will be resolved, but regardless of that, I would advise against ever having a const member variable in a struct. Even if you don't have any postblit issues, such a struct can never be assigned to, and it becomes essentially unusuable in any situation where you would have to assign a value to it (e.g. if it were in an array). You can certainly make a struct's member variable const if you want to, but you're going to run into stuff that won't work as a result. It's far better to just provide a property for it which is const (probably returning the member by const ref if you want to avoid copying it when using the property) rather than making the member variable itself const. - Jonathan M Davis