https://issues.dlang.org/show_bug.cgi?id=15507
--- Comment #4 from Jonathan M Davis <[email protected]> --- (In reply to Dicebot from comment #3) > Right. Well, this means my original concern remains. Overly restrictive > method attributes in base classes has caused me more trouble than lack of > any attributes there. I have no idea how to make stuff like `pure` or > `nothrow` to work with overriding when it comes to some very base abstract > methods. You're basically forced to decide which set of restrictions you want, and all derived classes are stuck with them. Do you want to be able to use the function in pure code? Then it has to be pure. But if you want to be able to do stuff in derived classes that isn't pure, then you can't make it pure... Basically, attributes and inheritance do not play along nicely at all. That's why we decided to remove opEquals, opCmp, toString, and toHash from Object - you can't possibly get the attributes right for everyone (though unfortunately, progress towards actually removing them has been minimal). So, we have to decide whether it makes sense to restrict message to be nothrow, pure, etc. or whether it makes sense to restrict the caller such that it has to handle exceptions from message to be nothrow or make it so that it can't be pure. nothrow almost certainly makes sense - certainly, I can see there being a good argument for considering it an Error for message to not work, and I seriously doubt that anyone is going to be handling exceptions thrown from the message member of an existing exception. pure _might_ make sense (certainly, ideally it would be pure - but it would mean that to do stuff like have a static variable, it would require a member variable that referred to that static variable), but it would make some implementations more unwieldy (e.g. using a static variable). Ultimately, all pure would be doing here is making it so that you can call message in pure code and so that you have to work at it to access mutable, "global" variables (and thus won't do it accidentally). It doesn't really prevent you from doing anything, but it doesn't protect you from much either, and it definitely doesn't enable any optimizations. However, the fact that pure _can_ be gotten around in this case via member variables but that you can't sanely get around the fact that the function isn't pure if you want to call it in pure code does make it seem like making it pure is the more flexible choice. @safe though is actually pretty questionable when you consider that there's a decent chance that an exception class would have the const(char)[] be a slice of a static array if it's trying to avoid allocations. To be safe, anyone who wants to save the message needs to (i)dup it (and actually, the documentation should probably reflect that). A lot of it comes down to whether we want to restrict the caller more or the classes that override message more. If I had to pick right now, I'd go with @system pure nothrow. --
