folly/dynamic fix use of incomplete type in template definition
authorYiding Jia <yiding@fb.com>
Thu, 29 Nov 2012 22:34:41 +0000 (14:34 -0800)
committerJordan DeLong <jdelong@fb.com>
Sun, 16 Dec 2012 22:46:07 +0000 (14:46 -0800)
Summary:
the old code is ill-formed per spec (section 14.6.8):

> If a type used in a non-dependent name is incomplete at the point at which a
> template is defined but is complete at the point at which an instantiation is
> done, and if the completeness of that type affects whether or not the program
> is well-formed or affects the semantics of the program, the program is
> ill-formed; no diagnostic is required.

GCC is lax and allows this, clang gives an error.

Test Plan: compiles.

Reviewed By: delong.j@fb.com

FB internal diff: D643431

folly/dynamic-inl.h

index 1942452c5feb627366b4aa9fcfd531ea424f97c4..4a9d99107c097cb9cc712883b312440fc0e24714 100644 (file)
@@ -58,6 +58,22 @@ struct hash< ::folly::dynamic> {
 
 namespace folly {
 
+struct TypeError : std::runtime_error {
+  explicit TypeError(const std::string& expected, dynamic::Type actual)
+    : std::runtime_error(to<std::string>("TypeError: expected dynamic "
+        "type `", expected, '\'', ", but had type `",
+        dynamic::typeName(actual), '\''))
+  {}
+  explicit TypeError(const std::string& expected,
+      dynamic::Type actual1, dynamic::Type actual2)
+    : std::runtime_error(to<std::string>("TypeError: expected dynamic "
+        "types `", expected, '\'', ", but had types `",
+        dynamic::typeName(actual1), "' and `", dynamic::typeName(actual2),
+        '\''))
+  {}
+};
+
+
 //////////////////////////////////////////////////////////////////////
 
 namespace detail {
@@ -128,21 +144,6 @@ namespace detail {
 
 //////////////////////////////////////////////////////////////////////
 
-struct TypeError : std::runtime_error {
-  explicit TypeError(const std::string& expected, dynamic::Type actual)
-    : std::runtime_error(to<std::string>("TypeError: expected dynamic "
-        "type `", expected, '\'', ", but had type `",
-        dynamic::typeName(actual), '\''))
-  {}
-  explicit TypeError(const std::string& expected,
-      dynamic::Type actual1, dynamic::Type actual2)
-    : std::runtime_error(to<std::string>("TypeError: expected dynamic "
-        "types `", expected, '\'', ", but had types `",
-        dynamic::typeName(actual1), "' and `", dynamic::typeName(actual2),
-        '\''))
-  {}
-};
-
 /*
  * We're doing this instead of a simple member typedef to avoid the
  * undefined behavior of parameterizing std::unordered_map<> with an