Bug 18934 – std.concurrency receive throws assertion failure if message is a struct containing const data

Status
RESOLVED
Resolution
FIXED
Severity
blocker
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2018-06-02T09:42:15Z
Last change time
2018-06-17T05:43:38Z
Keywords
pull, rejects-valid
Assigned to
Steven Schveighoffer
Creator
Russel Winder

Attachments

IDFilenameSummaryContent-TypeSize
1699receiveBreaksWithThisMessage.dCode exhibiting the errorapplication/x-dsrc843

Comments

Comment #0 by russel — 2018-06-02T09:42:15Z
If a message that is a struct comprising a struct is sent from one process to another using std.concurrency send, then the std.concurrency receive throws an assertion fail. The code I shall attach to this issue, when run using rdmd (2.080 from d-apt) on Debian Sid gives the following: |> rdmd receiveBreaksWithThisMessage.d Receiver going into receive. Sender sending. Sender finished. Receiver receive threw core.exception.AssertError@/usr/include/dmd/phobos/std/variant.d(323): Message ---------------- ??:? _d_assert_msg [0xa362e3a6] ??:? bool std.variant.VariantN!(32uL).VariantN.handler!(receiveBreaksWithThisMessage.Message).handler(std.variant.VariantN!(32uL).VariantN.OpID, ubyte[32]*, void*).tryPutting(receiveBreaksWithThisMessage.Message*, TypeInfo, void*) [0xa361d793] ??:? long std.variant.VariantN!(32uL).VariantN.handler!(receiveBreaksWithThisMessage.Message).handler(std.variant.VariantN!(32uL).VariantN.OpID, ubyte[32]*, void*) [0xa361d341] ??:? inout @property inout(receiveBreaksWithThisMessage.Message) std.variant.VariantN!(32uL).VariantN.get!(receiveBreaksWithThisMessage.Message).get() [0xa3628643] ??:? void std.concurrency.Message.map!(void function(receiveBreaksWithThisMessage.Message) @safe*).map(void function(receiveBreaksWithThisMessage.Message) @safe*) [0xa3628600] ??:? bool std.concurrency.MessageBox.get!(void function(receiveBreaksWithThisMessage.Message) @safe*).get(scope void function(receiveBreaksWithThisMessage.Message) @safe*).onStandardMsg(ref std.concurrency.Message) [0xa362803f] ??:? bool std.concurrency.MessageBox.get!(void function(receiveBreaksWithThisMessage.Message) @safe*).get(scope void function(receiveBreaksWithThisMessage.Message) @safe*).scan(ref std.concurrency.List!(std.concurrency.Message).List) [0xa36283e7] ??:? bool std.concurrency.MessageBox.get!(void function(receiveBreaksWithThisMessage.Message) @safe*).get(scope void function(receiveBreaksWithThisMessage.Message) @safe*) [0xa3627f7a] ??:? void std.concurrency.receive!(void function(receiveBreaksWithThisMessage.Message) @safe*).receive(void function(receiveBreaksWithThisMessage.Message) @safe*) [0xa3627e09] ??:? void receiveBreaksWithThisMessage.receiver() [0xa361c387] ??:? void std.concurrency._spawn!(void function()*)._spawn(bool, void function()*).exec() [0xa362b663] ??:? void core.thread.Thread.run() [0xa362f3a3] ??:? thread_entryPoint [0xa363f23f] ??:? [0x4a4e25a9] Receiver finished.
Comment #1 by russel — 2018-06-02T09:43:52Z
Created attachment 1699 Code exhibiting the error
Comment #2 by schveiguy — 2018-06-04T11:49:47Z
The issue comes from std.variant.Variant checking the wrong thing when it comes to constancy. A smaller test case: import std.variant; import std.stdio; struct S { const int x; } void main() { Variant v = S(1); writeln(v.get!S); // error } The issue is with the check inside std.variant to see if you can copy the given type to the requested type. The type matches, but the copy would normally fail because you can't overwrite const data. However, in the case of v.get!S, it's a move and not a copy. The check should be on moving the data, not copying. I have tested a fix, will submit a PR.
Comment #3 by schveiguy — 2018-06-04T15:13:27Z
Comment #4 by github-bugzilla — 2018-06-17T05:43:37Z
Commits pushed to master at https://github.com/dlang/phobos https://github.com/dlang/phobos/commit/2de6f8da22615e97e016a0e7aecb39f6d5e322d0 Fix issue 18934 - make std.variant support getting types that have const members. https://github.com/dlang/phobos/commit/cc961daf3220df387a1ae48b8e7c938ce6dee8da Merge pull request #6544 from schveiguy/fix18934 Fix issue 18934 - make std.variant support getting types that have const members