How to workaround on this (bug?)

Quirin Schroll qs.il.paperinik at gmail.com
Fri Sep 23 09:19:59 UTC 2022


On Friday, 16 September 2022 at 22:43:43 UTC, frame wrote:
> ```d
> import std.variant;
>
> // error: destructor `std.variant.VariantN!32LU.VariantN.~this` 
> is not `nothrow`
> void fun(Variant v) nothrow
> {
>
> }
>
> void main()
> {
>    fun(Variant());
> }
> ```
>
> A reference, pointer or slice works. I could do something on 
> the caller site but the signature of `fun()` should remain like 
> above.

A reference effectively is a never-`null` pointer. A slice is a 
pointer to the first of many objects plus the number of those 
objects (or empty, or `null`).
It boils down to pointers, and the pointed-to `Variant` object is 
not the responsibility of `fun`.

When you have a parameter that binds by copy, you cannot escape 
from calling its destructor, and if one happens not to be 
`nothrow`, your function cannot be `nothrow`.

The new semantics for `in` (compile with `-preview=in`) might 
work for you. The `in` storage class binds by copy if the copy is 
cheap – which I suspect is never the case for a `Variant` – or 
else by reference; and it can bind temporaries by reference 
(unlike `ref`). However, `in` also incurs `const` and `scope`. It 
is unlikely that `scope` will be your problem, but `const` very 
well might be an issue when the contained value has indirections  
to mutable values, e.g. an `int[]` will be read as a 
`const(int)[]`.

Calling the destructor is then the responsibility of the caller.

```d
// Compile with -preview=in

import std.variant;

void fun(in Variant v) nothrow { }

void main()
{
     fun(Variant()); // okay: `in` binds rvalues
     Variant v;
     fun(v); // okay: `in` binds lvalues
}
```


More information about the Digitalmars-d-learn mailing list