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