From 407e633f8072ed8317a9e4197d35ff33e19393ba Mon Sep 17 00:00:00 2001
From: Yiding Jia <yiding@fb.com>
Date: Thu, 29 Nov 2012 14:34:41 -0800
Subject: [PATCH] folly/dynamic fix use of incomplete type in template
 definition

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 | 31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/folly/dynamic-inl.h b/folly/dynamic-inl.h
index 1942452c..4a9d9910 100644
--- a/folly/dynamic-inl.h
+++ b/folly/dynamic-inl.h
@@ -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
-- 
2.34.1