On 4/1/22 6:22 PM, Vijay Nayar wrote:
Consider the following program:
```d
void main()
{
   import std.stdio;
   import std.container.rbtree;
   import std.variant;

   // alias Type = int;  // Works with no problem.
   alias Type = Variant; // Produces error.

   auto rbTree = new RedBlackTree!(Type);
   rbTree.stableInsert(Type(3));
   rbTree.stableInsert(Type(2));
   rbTree.stableInsert(Type(4));
   foreach (v; rbTree.upperBound(Type(2))) {
     writeln(v);
   }
}
```

A `RedBlackTree` constructs and runs perfectly fine using "int" as the data type, but it seems to blow up as soon as I use `std.variant : Variant`.

```
Compilation output (1: )

/dlang/dmd/linux/bin64/../../src/phobos/std/container/rbtree.d(1116): Error: `@safe` function `std.container.rbtree.RedBlackTree!(VariantN!32LU, "a < b", false).RedBlackTree.toHash` cannot call `@system` function `std.container.rbtree.RBRange!(RBNode!(VariantN!32LU)*).RBRange.front` /dlang/dmd/linux/bin64/../../src/phobos/std/container/rbtree.d(682): `std.container.rbtree.RBRange!(RBNode!(VariantN!32LU)*).RBRange.front` is declared here /dlang/dmd/linux/bin64/../../src/phobos/std/container/rbtree.d(1116): Error: destructor `std.variant.VariantN!32LU.VariantN.~this` is not `nothrow` /dlang/dmd/linux/bin64/../../src/phobos/std/container/rbtree.d(1113): Error: function `std.container.rbtree.RedBlackTree!(VariantN!32LU, "a < b", false).RedBlackTree.toHash` may throw but is marked as `nothrow` onlineapp.d(10): Error: template instance `std.container.rbtree.RedBlackTree!(VariantN!32LU, "a < b", false)` error instantiating
```

The issue is that for some reason redblacktree declares a `@safe nothrow toHash` function.

https://github.com/dlang/phobos/blob/99e9c1b7741e0f4e6f2a8c14883c4828d092701d/std/container/rbtree.d#L1113

I'm not sure why that is. But just copying a Variant is not `@safe nothrow`. So this explains why it's not working.

RBT should detect whether it can call the toHash with the appropriate attributes and declare it based on that.

-Steve

Reply via email to