From dc8fd00f5396f9eddf855557393157875c0f9b64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chaloupka?= Date: Sat, 2 Mar 2019 12:06:12 +0100 Subject: [PATCH 1/2] Fix #1941 - real fix for the workaround --- data/vibe/data/serialization.d | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/data/vibe/data/serialization.d b/data/vibe/data/serialization.d index bee7075a02..4e91f89eee 100644 --- a/data/vibe/data/serialization.d +++ b/data/vibe/data/serialization.d @@ -1199,11 +1199,15 @@ private template isBuiltinTuple(T, string member) } // heuristically determines @safe'ty of the serializer by testing readValue and writeValue for type int -private enum isSafeSerializer(S) = __traits(compiles, (S s) @safe { +private template isSafeSerializer(S) +{ alias T = Traits!(int, DefaultPolicy); - s.writeValue!T(42); - s.readValue!(T, int)(); -}); + static if (__traits(hasMember, S, "writeValue")) + enum isSafeSerializer = __traits(compiles, (S s) @safe { s.writeValue!T(42); }); + else static if (__traits(hasMember, S, "readValue")) + enum isSafeSerializer = __traits(compiles, (S s) @safe { s.readValue!(T, int)(); }); + else static assert(0, "Serializer without writeValue or readValue is invalid"); +} private template hasAttribute(T, alias decl) { enum hasAttribute = findFirstUDA!(T, decl).found; } From 9d054407fb0fab8c0a87a8612cb12b51770ea909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chaloupka?= Date: Fri, 8 Mar 2019 09:40:54 +0100 Subject: [PATCH 2/2] split isSafeSerializer --- data/vibe/data/serialization.d | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/data/vibe/data/serialization.d b/data/vibe/data/serialization.d index 4e91f89eee..06d6793305 100644 --- a/data/vibe/data/serialization.d +++ b/data/vibe/data/serialization.d @@ -572,7 +572,7 @@ private template deserializeValueImpl(Serializer, alias Policy) { static assert(Serializer.isSupportedValueType!(typeof(null)), "All serializers must support null values."); // work around https://issues.dlang.org/show_bug.cgi?id=16528 - static if (isSafeSerializer!Serializer) { + static if (isSafeDeserializer!Serializer) { T deserializeValue(T, ATTRIBUTES...)(ref Serializer ser) @safe { return deserializeValueDeduced!(T, ATTRIBUTES)(ser); } } else { T deserializeValue(T, ATTRIBUTES...)(ref Serializer ser) { return deserializeValueDeduced!(T, ATTRIBUTES)(ser); } @@ -1204,9 +1204,16 @@ private template isSafeSerializer(S) alias T = Traits!(int, DefaultPolicy); static if (__traits(hasMember, S, "writeValue")) enum isSafeSerializer = __traits(compiles, (S s) @safe { s.writeValue!T(42); }); - else static if (__traits(hasMember, S, "readValue")) - enum isSafeSerializer = __traits(compiles, (S s) @safe { s.readValue!(T, int)(); }); - else static assert(0, "Serializer without writeValue or readValue is invalid"); + else static assert(0, "Serializer is missing required writeValue method"); +} + +// heuristically determines @safe'ty of the deserializer by testing readValue and writeValue for type int +private template isSafeDeserializer(S) +{ + alias T = Traits!(int, DefaultPolicy); + static if (__traits(hasMember, S, "readValue")) + enum isSafeDeserializer = __traits(compiles, (S s) @safe { s.readValue!(T, int)(); }); + else static assert(0, "Deserializer is missing required readValue method"); } private template hasAttribute(T, alias decl) { enum hasAttribute = findFirstUDA!(T, decl).found; } @@ -1344,6 +1351,7 @@ private template getExpandedFieldsData(T, FIELDS...) version (unittest) { static assert(isSafeSerializer!TestSerializer); + static assert(isSafeDeserializer!TestSerializer); private struct TestSerializer { import std.array, std.conv, std.string;