libmir/asdf

Deserealizing struct with immutable members using proxy yields default values

Superbelko opened this issue · 3 comments

Problem: the following code produces default values on deserialization in Name structure
Expected: actual values from json in Name structure

Could be a compiler bug, no idea.
Compilers: DMD 2.098, LDC 1.28.0-beta1 (2.098 backend)

@serdeProxy!string
struct Name
{
        // immutable causes asdf to silently swallow error "can't assign 'this' in struct with immutable members"
        // comment out 'immutable' to make it work as expected
        immutable string godot;
        immutable string d;

        this(string godotName)
        {
                godot = godotName;
                d = godotName.dTypeName;
        }
}
struct Constant
{
        Name name; // <- BUG: will be default initialized instead of expected values
        int value;
}
struct Enum
{
        string name;
        Constant[] values;
}

Enum e = json.deserialize!(Enum);

test.json:

{
  "name": "Mode",
  "values": [
      {
        "name": "MODE_ECB_ENCRYPT",
        "value": 0
      },
  ]
}

Now however if I use this Constant instead I got compile error

struct Constant
{
        Name name; // case
        int value;

        SerdeException deserializeFromAsdf(Asdf data)
        {
            string val;
            if (auto exc = deserializeScopedString(data, val))
                return exc;
            // Error: cannot modify struct instance `this` of type `Constant` because it contains `const` or `immutable` members
            this = Constant(Name(val), 0 );
            return null;
        }
}
9il commented

Name isn't mutable member so it can't be deserialised because deserialiser can't set it.

To be honest you don't need to have immutable members in structs at all. It is very rare when they are really required.

9il commented

If you make Name a class I expect it would work. If not please modify and reopen this issue.

Ok, got it, thanks.
Though that wasn't my code, just got that thing to work with and had to do happy debugging on it.

Anyway this is one of CTFE sucks moment when it silently eats errors, so I posted it here so people would be able to find it.