Missing Future/SemiFuture->Value conversion check
authorLee Howes <lwh@fb.com>
Fri, 3 Nov 2017 17:16:04 +0000 (10:16 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Fri, 3 Nov 2017 17:40:06 +0000 (10:40 -0700)
Summary: Conversion check was lost in an earlier refactor. This meant that SemiFuture could be accidentally converted to Future through the value constructor. This should be disabled.

Reviewed By: yfeldblum

Differential Revision: D6214526

fbshipit-source-id: 3fc2d026ec6062b38b9500c8adf3eee12c0f2693

folly/futures/Future-pre.h
folly/futures/Future.h

index 26d9c7c6bb99316d4a0af3aa139267b845061ea6..82a8684cbfc468ae512a4857b1c4fc6b2ba4189f 100644 (file)
@@ -35,11 +35,6 @@ struct isSemiFuture<SemiFuture<T>> : std::true_type {
   typedef T Inner;
 };
 
   typedef T Inner;
 };
 
-template <typename T>
-struct isSemiFuture<Future<T>> : std::true_type {
-  typedef T Inner;
-};
-
 template <typename T>
 struct isFuture : std::false_type {
   using Inner = typename Unit::Lift<T>::type;
 template <typename T>
 struct isFuture : std::false_type {
   using Inner = typename Unit::Lift<T>::type;
index 5cd5436d0d049cf8c7e37e0ff5181317d271ab03..e6fc8ebeeacaa3102d994151fcda212c4e6efda3 100644 (file)
@@ -209,7 +209,8 @@ class SemiFuture : private futures::detail::FutureBase<T> {
   template <
       class T2 = T,
       typename = typename std::enable_if<
   template <
       class T2 = T,
       typename = typename std::enable_if<
-          !isFuture<typename std::decay<T2>::type>::value>::type>
+          !isFuture<typename std::decay<T2>::type>::value &&
+          !isSemiFuture<typename std::decay<T2>::type>::value>::type>
   /* implicit */ SemiFuture(T2&& val) : Base(std::forward<T2>(val)) {}
 
   template <class T2 = T>
   /* implicit */ SemiFuture(T2&& val) : Base(std::forward<T2>(val)) {}
 
   template <class T2 = T>
@@ -343,7 +344,8 @@ class Future : private futures::detail::FutureBase<T> {
   template <
       class T2 = T,
       typename = typename std::enable_if<
   template <
       class T2 = T,
       typename = typename std::enable_if<
-          !isFuture<typename std::decay<T2>::type>::value>::type>
+          !isFuture<typename std::decay<T2>::type>::value &&
+          !isSemiFuture<typename std::decay<T2>::type>::value>::type>
   /* implicit */ Future(T2&& val) : Base(std::forward<T2>(val)) {}
 
   template <class T2 = T>
   /* implicit */ Future(T2&& val) : Base(std::forward<T2>(val)) {}
 
   template <class T2 = T>