I've spent a lot of time trying to get workarounds that don't suck completely, but in the end I still expect this should "Just Work".
import std.stdio;
import std.variant;
void main(){
Variant[] top, bottom;
top = new Variant[](1);
bottom = new Variant[](1);
bottom[0] = "bar";
top[0] = bottom;
writeln(top[0][0]); // This works
top[0][0] = "foo"; // This does not
writeln(top[0][0]);
}
//Output:
bar
std.variant.VariantException@std/variant.d(1231): Variant: attempting to use incompatible types immutable(char)[] and std.variant.VariantN!(32LU).VariantN
----------------
./variantNest(@trusted long std.variant.VariantN!(32uL).VariantN.handler!(std.variant.VariantN!(32uL).VariantN[]).handler(std.variant.VariantN!(32uL).VariantN.OpID, ubyte[32]*, void*)+0x4e7) [0x44324f]
./variantNest(@trusted std.variant.VariantN!(32uL).VariantN std.variant.VariantN!(32uL).VariantN.opIndexAssign!(immutable(char)[], int).opIndexAssign(immutable(char)[], int)+0x10f) [0x447757]
./variantNest(_Dmain+0x245) [0x43b40d]
./variantNest(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void runMain()+0x18) [0x44d884]
./variantNest(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void tryExec(scope void delegate())+0x2a) [0x44d3b6]
./variantNest(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void runAll()+0x40) [0x44d8d4]
./variantNest(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void tryExec(scope void delegate())+0x2a) [0x44d3b6]
./variantNest(_d_run_main+0x1ae) [0x44d372]
./variantNest(main+0x17) [0x44d1bf]
/lib64/libc.so.6(__libc_start_main+0xfd) [0x7fad4d2a44bd]
----------------
Comment #1 by wyatt.epp — 2015-06-10T17:23:22Z
An NG post reminded me of this, so I just tested it on 2.067.1 and the output is rather different:
wyatt@Yue ~/tmp/d $ rdmd ./issue10223.d
bar
Segmentation fault
wyatt@Yue ~/tmp/d $
Okay, so it compiles now, but still doesn't work. We don't get nice things on Linux, so I tried it on my Windows workstation over lunch and found it's just been turned from a disappointment at compile time to a knife in the back at runtime:
[0s] jwe29@PC91534 ~/tmp $ rdmd ./issue10223.d
object.Error@(0): Access Violation
----------------
0x0042B626
0x00405141
0x00404667
0x004073D2
0x004021B1
0x0040B5E6
0x0040B5BB
0x0040B4D3
0x0040750B
0x7480337A in BaseThreadInitThunk
0x76F28FE2 in RtlInitializeExceptionChain
0x76F28FB5 in RtlInitializeExceptionChain
=== Bypassed ===
std.variant.VariantException@std\variant.d(1445): Variant: attempting to use incompatible types immutable(char)[] and std.variant.VariantN!20u.VariantN
----------------
0x004050E6
0x00404667
0x004073D2
0x004021B1
0x0040B5E6
0x0040B5BB
0x0040B4D3
0x0040750B
0x7480337A in BaseThreadInitThunk
0x76F28FE2 in RtlInitializeExceptionChain
0x76F28FB5 in RtlInitializeExceptionChain
object.Error@(0): Access Violation
----------------
0x0042B626
0x00405141
0x00404667
0x004073D2
0x004021B1
0x0040B5E6
0x0040B5BB
0x0040B4D3
0x0040750B
0x7480337A in BaseThreadInitThunk
0x76F28FE2 in RtlInitializeExceptionChain
0x76F28FB5 in RtlInitializeExceptionChain
=== ~Bypassed ===
bar
[2s] jwe29@PC91534 ~/tmp $
Comment #2 by bugzilla — 2019-12-28T16:22:20Z
I tried to hunt the bug down, but did only succeed partially. I'll write here, what I could find out. Maybe this is of some help for someone else:
* The crash happens inside of the @trusted part of the destructor of VariantN.
* When top[0][0] = "foo" is executed, opAssign is called twice, first with parameter "foo" and second with parameter 0, which is the value of the second bracket. Feels a little bit like this 0 is the wrong thing to assign here, but I'm not sure.
Comment #3 by robert.schadek — 2024-12-01T16:17:48Z