Making AssertError a singleton

Andrei Alexandrescu via Digitalmars-d digitalmars-d at puremagic.com
Tue Dec 13 14:47:55 PST 2016


On 12/13/2016 05:05 PM, Jonathan M Davis wrote:
> I mean that with virtual functions, in contracts get ||ed and out
> contracts get &&ed. Since that involves assertions, unless the compiler
> is doing something special there with assert, that involves throwing
> multiple AssertErrors and catching them. Depending on how that's
> implemented, having a singleton for AssertError would break that. If so,
> I expect that it's fixable, but simply turning AssertError into a
> singleton without verifying how that would affects contracts on virtual
> functions seems like a bad idea.

Yeah, that's the kind of feedback I was hoping for. Thanks.

Recall that all AssertError instances are equivalent up to file and 
line. It is possible that that causes issues but the likelihood is low. 
Overally I'm not too worried about this because contract handling is 
also under the control of the compiler/runtime so it doesn't break 
client code.

>>> It also could be problematic with unit tests - especially unit
>>> tests that catch AssertErrors (e.g. if someone wants to test the
>>> contracts).
>>
>> What kind of problems would it create?
>
> Well, if anyone is catching AssertErrors in unit tests, then they'll no
> longer be getting multiple of them. For some stuff, it wouldn't matter,
> but for other stuff it would break it. For instance, while the default
> test runner stops on the first failure in a unittest block, others are
> going to run them all and then print out the failures, and if
> AssertError is a singelton, then all of the AssertErrors that were
> stored to print at the end would then be the same AssertError and would
> print the same thing, defeating the purpose of the alternate test runner.

Would be quite cool if all failed assertions showed the same file and 
line, eh? :o)

I'm actually of a mind to push this in the language specification - 
Error objects are not guaranteed to be distinct. Errors already have a 
number of concessions and shouldn't be used naively.

>> Is reducing dependencies for core constructs a good thing?
>
> It is when it reduces functionality, which this does. It puts
> unnecessary restrictions on AssertError which are of zero benefit for
> the vast majority of D programs.

Probably a negation was meant somewhere.

>>> And if we fix it so that exceptions don't need the GC (which is arguably
>>> needed for @nogc to be widely used), then this whole problem goes away
>>> anyway. So, I'm inclined to argue that we just fix _that_ problem and
>>> not worry about the fact that assert currently triggers the GC on
>>> failure.
>>
>> I agree the perfect system would fix everything - problem is we don't
>> have it yet. The per-thread singleton is a step forward (which at some
>> point we should probably make publicly available).
>
> We _need_ to fix the fact that exceptions require the GC, or @nogc is
> utterly useless for large portions of D code simply because of the
> exceptions, which will make it much harder to use D without the GC. If
> we fix it so that exceptions don't need the GC, then this problem goes
> away, and these changes are just an unnecessary complication in druntime.

This kind of argument I honestly don't put too much in the balance 
because it promotes paralysis of analysis. Right now I don't know what 
to do to make all exceptions not use GC. I do know what to do to avoid 
using the GC in assert, and in my opinion at a negligible cost in 
amenities. We can't afford to refuse to take a step just because the 
journey is long.


Andrei



More information about the Digitalmars-d mailing list