| ... | @@ -1272,7 +1272,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing, | ... | @@ -1272,7 +1272,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing, |
| 1272 | return error.InvalidEnumTag; | 1272 | return error.InvalidEnumTag; |
| 1273 | } | 1273 | } |
| 1274 | @compileError("Cannot meaningfully deserialize " ++ @typeName(C) ++ | 1274 | @compileError("Cannot meaningfully deserialize " ++ @typeName(C) ++ |
| 1275 | " because it is an untagged union Use a custom deserialize()."); | 1275 | " because it is an untagged union. Use a custom deserialize()."); |
| 1276 | }, | 1276 | }, |
| 1277 | builtin.TypeId.Optional => { | 1277 | builtin.TypeId.Optional => { |
| 1278 | const OC = comptime meta.Child(C); | 1278 | const OC = comptime meta.Child(C); |
| ... | @@ -1282,11 +1282,8 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing, | ... | @@ -1282,11 +1282,8 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing, |
| 1282 | return; | 1282 | return; |
| 1283 | } | 1283 | } |
| 1284 | | 1284 | |
| 1285 | //This should ensure that the optional is set to non-null. | 1285 | ptr.* = OC(undefined); //make it non-null so the following .? is guaranteed safe |
| 1286 | ptr.* = OC(undefined); | 1286 | const val_ptr = &ptr.*.?; |
| 1287 | //The way non-pointer optionals are implemented ensures a pointer to them | | |
| 1288 | // will point to the value. The flag is stored at the end of that data. | | |
| 1289 | var val_ptr = @ptrCast(*OC, ptr); | | |
| 1290 | try self.deserializeInto(val_ptr); | 1287 | try self.deserializeInto(val_ptr); |
| 1291 | }, | 1288 | }, |
| 1292 | builtin.TypeId.Enum => { | 1289 | builtin.TypeId.Enum => { |
| ... | @@ -1426,7 +1423,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co | ... | @@ -1426,7 +1423,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co |
| 1426 | unreachable; | 1423 | unreachable; |
| 1427 | } | 1424 | } |
| 1428 | @compileError("Cannot meaningfully serialize " ++ @typeName(T) ++ | 1425 | @compileError("Cannot meaningfully serialize " ++ @typeName(T) ++ |
| 1429 | " because it is an untagged union Use a custom serialize()."); | 1426 | " because it is an untagged union. Use a custom serialize()."); |
| 1430 | }, | 1427 | }, |
| 1431 | builtin.TypeId.Optional => { | 1428 | builtin.TypeId.Optional => { |
| 1432 | if (value == null) { | 1429 | if (value == null) { |
| ... | @@ -1436,10 +1433,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co | ... | @@ -1436,10 +1433,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co |
| 1436 | try self.serializeInt(u1(@boolToInt(true))); | 1433 | try self.serializeInt(u1(@boolToInt(true))); |
| 1437 | | 1434 | |
| 1438 | const OC = comptime meta.Child(T); | 1435 | const OC = comptime meta.Child(T); |
| 1439 | | 1436 | const val_ptr = &value.?; |
| 1440 | //The way non-pointer optionals are implemented ensures a pointer to them | | |
| 1441 | // will point to the value. The flag is stored at the end of that data. | | |
| 1442 | var val_ptr = @ptrCast(*const OC, &value); | | |
| 1443 | try self.serialize(val_ptr.*); | 1437 | try self.serialize(val_ptr.*); |
| 1444 | }, | 1438 | }, |
| 1445 | builtin.TypeId.Enum => { | 1439 | builtin.TypeId.Enum => { |