Can std.variant be used with std.container.rbtree?

Steven Schveighoffer schveiguy at gmail.com
Sat Apr 2 16:25:13 UTC 2022


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


More information about the Digitalmars-d-learn mailing list