RFC: reference counted Throwable
via Digitalmars-d
digitalmars-d at puremagic.com
Sat Sep 20 05:33:37 PDT 2014
On Saturday, 20 September 2014 at 11:50:28 UTC, Marc Schütz wrote:
> On Saturday, 20 September 2014 at 09:19:21 UTC, Dicebot wrote:
>> Yeah but implicitly convertible to what? If you convert it to
>> `Throwable` your reference counting facilities are
>> circumvented resulting in dangling exception reference at
>> point where `Throwable` gets caught.
>
> As I said, throw/catch is at its core a moving operation. For
> classes this isn't important (they are references), but for an
> RC wrapper it would be, so we could specify that.
>
> Move-constructing from an lvalue in the context of D can be
> seen as a three-step process:
>
> 1) create a temporary, initialize with T.init
> 2) bit-swap the variable with the temporary
> 3) destroy the variable
>
> It can be seen that the value that is to be moved (the RC
> wrapper) must be non-const (only at the head, it may still be
> tail-const).
>
> Now, any generic RC type that wants to be implicitly
> convertible to its payload type must do this via borrowing in
> order to be safe (see my proposal at [1]). Using
> const-borrowing, we can guarantee that the wrapper will not be
> thrown (or moved, in general) as long as borrowed references to
> its payload exist:
>
> struct RC(T) {
> // ...
> T _payload;
> scope!(const this) borrow() {
> return _payload;
> }
> alias borrow this;
> }
>
> This already solves avoiding dangling references to the
> exception: No references can be left behind when the exception
> is thrown, and the wrapper will not be destroyed, but moved,
> thus not releasing the exception's memory.
>
> The second part is really "just" some way to transport the
> wrapper via the exception mechanism, including support for
> catching wrappers of derived exception types.
>
>>
>> Special casing catching such wrappers to still preserve
>> original ref-counted type while pretending to be Throwable at
>> call site sounds like a terrible hack, much worse than any
>> sort of ARC complexity.
>
> IMO it would only a hack _if_ they were indeed special cased.
> I'm sure we can find a more generic mechanism that would allow
> this to be implemented cleanly. Note that the other
> requirements I described above (borrowing, move semantics) are
> also things that just happen to be usable here: they are
> desirable in general, exceptions are just one possible
> application.
>
> [1] http://wiki.dlang.org/User:Schuetzm/scope
The mechanism might simply be to allow anything to be thrown that
a) supports moving, e.g. provides a method `release()` that
returns a unique expression (this requires moving and uniqueness
to be specified first, which is a good idea anyway), and
b) is implicitly convertible to Throwable.
More information about the Digitalmars-d
mailing list