Skip to content

POCO structs are treated as unmanaged despite GenerateType.VersionTolerant #300

@Rurouni

Description

@Rurouni

Hi, we've recently run into an unforeseen backward compatibility issue in such scenario:

  1. let's say we have such struct in protocol
[MemoryPackable(GenerateType.VersionTolerant)]
public partial struct SomeStruct
{
    [MemoryPackOrder(0)] public int SomeField1;
    [MemoryPackOrder(1)] public int SomeField2;
}
  1. next we add another field
[MemoryPackable(GenerateType.VersionTolerant)]
public partial struct SomeStruct
{
    [MemoryPackOrder(0)] public int SomeField1;
    [MemoryPackOrder(1)] public int SomeField2;
    [MemoryPackOrder(2)] public int NewField;
}

Expectation: based on docs, we expected the old data would be still compatible just result in NewField getting default value on deserialisation

Actual Behavior: The struct is treated as unmanaged type, and the generated formatter does basic memcopy, ignoring GenerateType.VersionTolerant

From my initial investigation, it appears that problem lies in

this.IsUnmanagedType = symbol.IsUnmanagedType;
so as soon as Roslyn tells us that it's unmanaged struct we treat it as unmanaged type disregarding GenerateType in attribute

This is quite dangerous, as one can expect the protocol to be backwards compatible if you use GenerateType.VersionTolerant and adheres to rules, but even adding a new property will make old data unreadable.

Thank you

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions