From 2690ee57aad51321e5e97870dc30d36889c14d0c Mon Sep 17 00:00:00 2001
From: Eric Niebler <eniebler@boost.org>
Date: Tue, 16 Oct 2018 14:23:57 -0700
Subject: [PATCH] Use real concepts when they are available

fbshipit-source-id: bfecdc1c0e934cf073e610c2cb98518bfde84ecd
---
 folly/experimental/pushmi/include/pushmi.h    | 621 +++++++++++-------
 .../pushmi/include/pushmi/concepts.h          |  13 +-
 .../pushmi/include/pushmi/deferred.h          |  38 +-
 .../include/pushmi/detail/concept_def.h       | 227 +++++--
 .../pushmi/include/pushmi/flow_single.h       |  38 +-
 .../include/pushmi/flow_single_deferred.h     |  40 +-
 .../experimental/pushmi/include/pushmi/none.h |  77 +--
 .../pushmi/include/pushmi/o/defer.h           |   1 +
 .../pushmi/include/pushmi/properties.h        |   6 +-
 .../pushmi/include/pushmi/single.h            |  85 +--
 .../pushmi/include/pushmi/single_deferred.h   |  49 +-
 .../include/pushmi/time_single_deferred.h     |  47 +-
 12 files changed, 738 insertions(+), 504 deletions(-)

diff --git a/folly/experimental/pushmi/include/pushmi.h b/folly/experimental/pushmi/include/pushmi.h
index 2cdd5c999..c28e4c5e5 100644
--- a/folly/experimental/pushmi/include/pushmi.h
+++ b/folly/experimental/pushmi/include/pushmi.h
@@ -3872,33 +3872,32 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
 //                 t = (U &&) u,
 //                 ::pushmi::concepts::requires_<Same<decltype(t = (U &&) u), T>>
 //             ) &&
-//             std::is_lvalue_reference<T>{}
+//             std::is_lvalue_reference_v<T>
 //     );
 #define PUSHMI_CONCEPT_DEF(DECL, ...)                                          \
     PUSHMI_PP_EVAL(                                                            \
         PUSHMI_PP_DECL_DEF,                                                    \
         PUSHMI_PP_CAT(PUSHMI_PP_DEF_DECL_, DECL),                              \
-        __VA_ARGS__,                                                           \
-        PUSHMI_PP_EAT)                                                         \
+        __VA_ARGS__)                                                           \
+    /**/
+#define PUSHMI_PP_DECL_DEF_NAME(...)                                           \
+    __VA_ARGS__,                                                               \
     /**/
-#define PUSHMI_PP_DECL_DEF_NAME(...) __VA_ARGS__,
-#define PUSHMI_PP_DECL_DEF(TPARAM, NAME, REQUIRES, ...)                        \
+#define PUSHMI_PP_DECL_DEF(TPARAM, NAME, ...)                                  \
     PUSHMI_PP_CAT(PUSHMI_PP_DECL_DEF_, PUSHMI_PP_IS_PAREN(NAME))(              \
         TPARAM,                                                                \
         NAME,                                                                  \
-        REQUIRES,                                                              \
         __VA_ARGS__)                                                           \
     /**/
 // The defn is of the form:
 //   template(class A, class B = void, class... Rest)
 //   (concept Name)(A, B, Rest...),
 //      // requirements...
-#define PUSHMI_PP_DECL_DEF_1(TPARAM, NAME, REQUIRES, ...)                      \
+#define PUSHMI_PP_DECL_DEF_1(TPARAM, NAME, ...)                                \
     PUSHMI_PP_EVAL4(                                                           \
         PUSHMI_PP_DECL_DEF_IMPL,                                               \
         TPARAM,                                                                \
         PUSHMI_PP_DECL_DEF_NAME NAME,                                          \
-        REQUIRES,                                                              \
         __VA_ARGS__)                                                           \
     /**/
 // The defn is of the form:
@@ -3906,12 +3905,11 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
 //   concept Name,
 //      // requirements...
 // Compute the template arguments (A, B) from the template introducer.
-#define PUSHMI_PP_DECL_DEF_0(TPARAM, NAME, REQUIRES, ...)                      \
+#define PUSHMI_PP_DECL_DEF_0(TPARAM, NAME, ...)                                \
     PUSHMI_PP_DECL_DEF_IMPL(                                                   \
         TPARAM,                                                                \
         NAME,                                                                  \
         (PUSHMI_PP_CAT(PUSHMI_PP_AUX_, TPARAM)),                               \
-        REQUIRES,                                                              \
         __VA_ARGS__)                                                           \
     /**/
 // Expand the template definition into a struct and template alias like:
@@ -3927,17 +3925,83 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
 //    };
 //    template<class A, class B>
 //    inline constexpr bool Name = NameConcept::is_satisfied_by<A, B>(0);
-#define PUSHMI_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, REQUIRES, ...)             \
+#if __cpp_concepts
+// No requires expression
+#define PUSHMI_PP_DEF_IMPL_0(...)                                              \
+    __VA_ARGS__                                                                \
+    /**/
+// Requires expression
+#define PUSHMI_PP_DEF_IMPL_1(...)                                              \
+    PUSHMI_PP_CAT(PUSHMI_PP_DEF_IMPL_1_, __VA_ARGS__)                          \
+    /**/
+#define PUSHMI_PP_DEF_IMPL_1_requires                                          \
+    requires PUSHMI_PP_DEF_IMPL_1_REQUIRES                                     \
+    /**/
+#define PUSHMI_PP_DEF_IMPL_1_REQUIRES(...)                                     \
+    (__VA_ARGS__) PUSHMI_PP_DEF_IMPL_1_REQUIRES_BODY                           \
+    /**/
+#define PUSHMI_PP_DEF_IMPL_1_REQUIRES_BODY(...)                                \
+    { __VA_ARGS__; }                                                           \
+    /**/
+#define PUSHMI_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, ...)                       \
+    inline namespace pushmi_concept_eager {                                    \
+        PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM)                                  \
+        concept bool PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME) = PUSHMI_PP_EVAL2(    \
+            PUSHMI_PP_DEF_IMPL(__VA_ARGS__),                                   \
+            __VA_ARGS__);                                                      \
+    }                                                                          \
+    namespace defer = pushmi_concept_eager;                                    \
+    namespace lazy {                                                           \
+        PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM)                                  \
+        struct PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) {   \
+            using Concept =                                                    \
+                PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept);   \
+            explicit constexpr operator bool() const noexcept {                \
+                return (bool) defer::PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME)<      \
+                    PUSHMI_PP_EXPAND ARGS>;                                    \
+            }                                                                  \
+            constexpr auto operator!() const noexcept {                        \
+                return ::pushmi::concepts::detail::Not<Concept>{};             \
+            }                                                                  \
+            template <class That>                                              \
+            constexpr auto operator&&(That) const noexcept {                   \
+                return ::pushmi::concepts::detail::And<Concept, That>{};       \
+            }                                                                  \
+        };                                                                     \
+        PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM)                                  \
+        PUSHMI_INLINE_VAR constexpr auto PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME) = \
+            PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept)        \
+                <PUSHMI_PP_EXPAND ARGS>{};                                     \
+    }                                                                          \
+    /**/
+#else
+// No requires expression:
+#define PUSHMI_PP_DEF_IMPL_0(...)                                              \
+    () -> std::enable_if_t<bool(__VA_ARGS__), int>                             \
+    /**/
+// Requires expression:
+#define PUSHMI_PP_DEF_IMPL_1(...)                                              \
+    PUSHMI_PP_CAT(PUSHMI_PP_DEF_IMPL_1_, __VA_ARGS__) ), int>                  \
+    /**/
+#define PUSHMI_PP_DEF_IMPL_1_requires                                          \
+    PUSHMI_PP_DEF_IMPL_1_REQUIRES                                              \
+    /**/
+#define PUSHMI_PP_DEF_IMPL_1_REQUIRES(...)                                     \
+    (__VA_ARGS__) -> std::enable_if_t<bool(                                    \
+        ::pushmi::concepts::detail::requires_  PUSHMI_PP_DEF_REQUIRES_BODY     \
+    /**/
+ #define PUSHMI_PP_DEF_REQUIRES_BODY(...)                                      \
+    <decltype(__VA_ARGS__, void())>()                                          \
+    /**/
+#define PUSHMI_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, ...)                       \
     struct PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) {       \
         using Concept =                                                        \
             PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept);       \
         PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN                                    \
         PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM)                                  \
         static auto _concept_requires_ PUSHMI_PP_EVAL2(                        \
-            PUSHMI_PP_DEF_WRAP,                                                \
-            PUSHMI_PP_CAT(PUSHMI_PP_DEF_, REQUIRES),                           \
-            REQUIRES,                                                          \
-            (__VA_ARGS__))(~) int>;                                            \
+            PUSHMI_PP_DEF_IMPL(__VA_ARGS__),                                   \
+            __VA_ARGS__);                                                      \
         PUSHMI_PP_IGNORE_CXX2A_COMPAT_END                                      \
         PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM)                                  \
         struct _is_satisfied_by_ {                                             \
@@ -3969,8 +4033,18 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
             PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept)        \
                 ::_is_satisfied_by_<PUSHMI_PP_EXPAND ARGS>{};                  \
     }                                                                          \
+    namespace defer = lazy;                                                    \
     /**/
+#endif
 
+#define PUSHMI_PP_REQUIRES_PROBE_requires                                      \
+    PUSHMI_PP_PROBE(~)                                                         \
+    /**/
+#define PUSHMI_PP_DEF_IMPL(REQUIRES, ...)                                      \
+    PUSHMI_PP_CAT(                                                             \
+        PUSHMI_PP_DEF_IMPL_,                                                   \
+        PUSHMI_PP_CHECK(PUSHMI_PP_CAT(PUSHMI_PP_REQUIRES_PROBE_, REQUIRES)))   \
+    /**/
 #define PUSHMI_PP_DEF_DECL_template(...)                                       \
     template(__VA_ARGS__),                                                     \
     /**/
@@ -3984,7 +4058,6 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
 #define PUSHMI_PP_DEF_bool
 #define PUSHMI_PP_DEF_size_t
 #define PUSHMI_PP_DEF_unsigned
-#define PUSHMI_PP_DEF_requires ~,
 #define PUSHMI_PP_AUX_template(...)                                            \
     PUSHMI_PP_CAT2(                                                            \
         PUSHMI_PP_TPARAM_,                                                     \
@@ -4001,63 +4074,95 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
 #define PUSHMI_PP_TPARAM_5(_1, ...)                                            \
     PUSHMI_PP_CAT2(PUSHMI_PP_DEF_, _1), PUSHMI_PP_TPARAM_4(__VA_ARGS__)
 
-#define PUSHMI_PP_DEF_WRAP(X, Y, ...)                                          \
-    PUSHMI_PP_EVAL3(                                                           \
-        PUSHMI_PP_CAT(PUSHMI_PP_DEF_WRAP_, PUSHMI_PP_COUNT(__VA_ARGS__)),      \
-        X,                                                                     \
-        Y,                                                                     \
-        __VA_ARGS__)                                                           \
+////////////////////////////////////////////////////////////////////////////////
+// PUSHMI_TEMPLATE
+// Usage:
+//   PUSHMI_TEMPLATE (class A, class B)
+//     (requires Concept1<A> && Concept2<B>)
+//   void foo(A a, B b)
+//   {}
+// or
+//   PUSHMI_TEMPLATE (class A, class B)
+//     (requires requires (expr1, expr2, expr3) && Concept1<A> && Concept2<B>)
+//   void foo(A a, B b)
+//   {}
+#if __cpp_concepts
+#define PUSHMI_TEMPLATE(...)                                                   \
+    template<__VA_ARGS__> PUSHMI_TEMPLATE_AUX_                                 \
     /**/
-
-// No requires expression:
-#define PUSHMI_PP_DEF_WRAP_1(_, HEAD, TAIL)                                    \
-    () -> std::enable_if_t<HEAD, PUSHMI_PP_EXPAND TAIL                         \
+#define PUSHMI_TEMPLATE_AUX_(...)                                              \
+    PUSHMI_TEMPLATE_AUX_4(PUSHMI_PP_CAT(PUSHMI_TEMPLATE_AUX_3_, __VA_ARGS__))  \
     /**/
-// Requires expression:
-#define PUSHMI_PP_DEF_WRAP_2(_a, HEAD, _b, TAIL)                               \
-    PUSHMI_PP_CAT(PUSHMI_PP_DEF_REQUIRES_, PUSHMI_PP_IS_PAREN(HEAD)) HEAD,     \
-    PUSHMI_PP_EXPAND TAIL                                                      \
+#define PUSHMI_TEMPLATE_AUX_3_requires
+#define PUSHMI_TEMPLATE_AUX_4(...)                                             \
+    PUSHMI_TEMPLATE_AUX_5(__VA_ARGS__)(__VA_ARGS__)                            \
     /**/
-// Requires expression without a requirement parameter list:
-#define PUSHMI_PP_DEF_REQUIRES_0                                               \
-    () -> decltype(::pushmi::concepts::detail::requires_                       \
-        PUSHMI_PP_DEF_REQUIRES_EXPRS                                           \
+#define PUSHMI_TEMPLATE_AUX_5(REQUIRES, ...)                                   \
+    PUSHMI_PP_CAT(                                                             \
+        PUSHMI_TEMPLATE_AUX_5_,                                                \
+        PUSHMI_PP_CHECK(PUSHMI_PP_CAT(PUSHMI_PP_REQUIRES_PROBE_, REQUIRES)))   \
     /**/
-// Requires expression with a requirement parameter list:
-#define PUSHMI_PP_DEF_REQUIRES_1(...)                                          \
-    (__VA_ARGS__) -> std::enable_if_t<::pushmi::concepts::detail::requires_    \
-        PUSHMI_PP_DEF_REQUIRES_EXPRS                                           \
+// No requires expression:
+#define PUSHMI_TEMPLATE_AUX_5_0(...)                                           \
+    requires __VA_ARGS__                                                       \
     /**/
-
-#define  PUSHMI_PP_DEF_REQUIRES_EXPRS(...) \
-    <decltype(__VA_ARGS__, void())>()\
+// Requires expression
+#define PUSHMI_TEMPLATE_AUX_5_1(...)                                           \
+    PUSHMI_PP_CAT(PUSHMI_TEMPLATE_AUX_6_, __VA_ARGS__)                         \
     /**/
-
-#define PUSHMI_TYPE_CONSTRAINT(X) class
-
+#define PUSHMI_TEMPLATE_AUX_6_requires(...)\
+    requires requires { __VA_ARGS__; }
+#else
 #define PUSHMI_TEMPLATE(...)                                                   \
     template<__VA_ARGS__ PUSHMI_TEMPLATE_AUX_
 #define PUSHMI_TEMPLATE_AUX_(...) ,                                            \
-    int (*PUSHMI_PP_CAT(_pushmi_concept_unique_, __LINE__))[PUSHMI_COUNTER] = nullptr,                  \
-    std::enable_if_t<PUSHMI_PP_CAT(_pushmi_concept_unique_, __LINE__) ||                                \
-        bool(PUSHMI_TEMPLATE_AUX_4(PUSHMI_PP_CAT(PUSHMI_TEMPLATE_AUX_3_, __VA_ARGS__))), int> = 0>
+    int (*PUSHMI_PP_CAT(_pushmi_concept_unique_, __LINE__))[                   \
+        PUSHMI_COUNTER] = nullptr,                                             \
+    std::enable_if_t<PUSHMI_PP_CAT(_pushmi_concept_unique_, __LINE__) ||       \
+        bool(PUSHMI_TEMPLATE_AUX_4(PUSHMI_PP_CAT(                              \
+            PUSHMI_TEMPLATE_AUX_3_, __VA_ARGS__))), int> = 0>                  \
+    /**/
 #define PUSHMI_TEMPLATE_AUX_3_requires
-#define PUSHMI_TEMPLATE_AUX_4(...) \
-    PUSHMI_PP_EVAL(\
-        PUSHMI_PP_CAT,\
-        PUSHMI_TEMPLATE_AUX_5_, \
-        PUSHMI_PP_IS_EQUAL(\
-            PUSHMI_PP_EVAL2(PUSHMI_PP_COUNT, PUSHMI_PP_CAT2(PUSHMI_TEMPLATE_AUX_5_, __VA_ARGS__)),\
-            PUSHMI_PP_EVAL2(PUSHMI_PP_COUNT, __VA_ARGS__)))(__VA_ARGS__)
-#define PUSHMI_TEMPLATE_AUX_5_requires ~,
-#define PUSHMI_TEMPLATE_AUX_5_0(...) \
-    PUSHMI_PP_CAT(PUSHMI_TEMPLATE_AUX_6_, __VA_ARGS__)
-#define PUSHMI_TEMPLATE_AUX_5_1(...) \
-    __VA_ARGS__
-#define PUSHMI_TEMPLATE_AUX_6_requires(...)\
-    ::pushmi::concepts::detail::requires_<decltype(__VA_ARGS__)>()
+#define PUSHMI_TEMPLATE_AUX_4(...)                                             \
+    PUSHMI_TEMPLATE_AUX_5(__VA_ARGS__)(__VA_ARGS__)                            \
+    /**/
+#define PUSHMI_TEMPLATE_AUX_5(REQUIRES, ...)                                   \
+    PUSHMI_PP_CAT(                                                             \
+        PUSHMI_TEMPLATE_AUX_5_,                                                \
+        PUSHMI_PP_CHECK(PUSHMI_PP_CAT(PUSHMI_PP_REQUIRES_PROBE_, REQUIRES)))   \
+    /**/
+// No requires expression:
+#define PUSHMI_TEMPLATE_AUX_5_0(...)                                           \
+    __VA_ARGS__                                                                \
+    /**/
+#define PUSHMI_TEMPLATE_AUX_5_1(...)                                           \
+    PUSHMI_PP_CAT(PUSHMI_TEMPLATE_AUX_6_, __VA_ARGS__)                         \
+    /**/
+#define PUSHMI_TEMPLATE_AUX_6_requires(...)                                    \
+    ::pushmi::concepts::detail::requires_<decltype(__VA_ARGS__)>()             \
+    /**/
+#endif
 
+
+#if __cpp_concepts
+#define PUSHMI_BROKEN_SUBSUMPTION(...) __VA_ARGS__ // BUGBUG
+#define PUSHMI_TYPE_CONSTRAINT(...) __VA_ARGS__
+#else
 #define PUSHMI_BROKEN_SUBSUMPTION(...) __VA_ARGS__
+#define PUSHMI_TYPE_CONSTRAINT(...) class
+#endif
+
+
+#if __cpp_concepts
+#define PUSHMI_PP_CONSTRAINED_USING(REQUIRES, NAME, TYPE)                      \
+    requires REQUIRES                                                          \
+  using NAME TYPE;                                                             \
+  /**/
+#else
+#define PUSHMI_PP_CONSTRAINED_USING(REQUIRES, NAME, TYPE)                      \
+  using NAME std::enable_if_t<bool(REQUIRES), TYPE>;                           \
+  /**/
+#endif
 
 namespace pushmi {
 namespace concepts {
@@ -5065,14 +5170,16 @@ struct property_query_impl :
   meta::and_c<decltype(property_query_fn<ExpectedN>((properties_t<PS>*)nullptr))::value...> {};
 } //namespace detail
 
-template<PUSHMI_TYPE_CONSTRAINT(Properties) PS, PUSHMI_TYPE_CONSTRAINT(Property)... ExpectedN>
+//template<PUSHMI_TYPE_CONSTRAINT(Properties) PS, PUSHMI_TYPE_CONSTRAINT(Property)... ExpectedN>
+template<class PS, class... ExpectedN>
 struct property_query
   : meta::if_c<
       Properties<PS> && And<Property<ExpectedN>...>,
       detail::property_query_impl<PS, ExpectedN...>,
       std::false_type> {};
 
-template<PUSHMI_TYPE_CONSTRAINT(Properties) PS, PUSHMI_TYPE_CONSTRAINT(Property)... ExpectedN>
+//template<PUSHMI_TYPE_CONSTRAINT(Properties) PS, PUSHMI_TYPE_CONSTRAINT(Property)... ExpectedN>
+template<class PS, class... ExpectedN>
 PUSHMI_INLINE_VAR constexpr bool property_query_v = property_query<PS, ExpectedN...>::value;
 
 } // namespace pushmi
@@ -5428,9 +5535,9 @@ PUSHMI_CONCEPT_DEF(
 );
 
 template <class D>
-using time_point_t =
-  std::enable_if_t<TimeSender<D>, decltype(::pushmi::now(std::declval<D&>()))>;
-
+PUSHMI_PP_CONSTRAINED_USING(
+  TimeSender<D>,
+  time_point_t =, decltype(::pushmi::now(std::declval<D&>())));
 
 // this is a more general form where the constraint could be time or priority
 // enum or any other ordering constraint value-type.
@@ -5464,10 +5571,9 @@ PUSHMI_CONCEPT_DEF(
 );
 
 template <class D>
-using constraint_t =
-  std::enable_if_t<
-    ConstrainedSender<D>,
-    decltype(::pushmi::top(std::declval<D&>()))>;
+PUSHMI_PP_CONSTRAINED_USING(
+  ConstrainedSender<D>,
+  constraint_t =, decltype(::pushmi::top(std::declval<D&>())));
 
 } // namespace pushmi
 //#pragma once
@@ -5784,21 +5890,8 @@ class none<E> {
     void (*error_)(data&, E) noexcept = s_error;
     static constexpr vtable const noop_ {};
   } const* vptr_ = &vtable::noop_;
-  template <class T, class U = std::decay_t<T>>
-  using wrapped_t =
-    std::enable_if_t<!std::is_same<U, none>::value, U>;
-public:
-  using properties = property_set<is_receiver<>, is_none<>>;
-
-  none() = default;
-  none(none&& that) noexcept : none() {
-    that.vptr_->op_(that.data_, &data_);
-    std::swap(that.vptr_, vptr_);
-  }
-  PUSHMI_TEMPLATE(class Wrapped)
-    (requires NoneReceiver<wrapped_t<Wrapped>, E>
-      PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
-  explicit none(Wrapped obj) : none() {
+  template <class Wrapped>
+  none(Wrapped obj, std::false_type) : none() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -5816,9 +5909,8 @@ public:
     data_.pobj_ = new Wrapped(std::move(obj));
     vptr_ = &vtable_v;
   }
-  PUSHMI_TEMPLATE(class Wrapped)
-    (requires NoneReceiver<wrapped_t<Wrapped>, E> && insitu<Wrapped>())
-  explicit none(Wrapped obj) noexcept : none() {
+  template <class Wrapped>
+  none(Wrapped obj, std::true_type) noexcept : none() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -5838,6 +5930,21 @@ public:
     new (data_.buffer_) Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
+  template <class T, class U = std::decay_t<T>>
+  using wrapped_t =
+    std::enable_if_t<!std::is_same<U, none>::value, U>;
+public:
+  using properties = property_set<is_receiver<>, is_none<>>;
+
+  none() = default;
+  none(none&& that) noexcept : none() {
+    that.vptr_->op_(that.data_, &data_);
+    std::swap(that.vptr_, vptr_);
+  }
+  PUSHMI_TEMPLATE(class Wrapped)
+    (requires NoneReceiver<wrapped_t<Wrapped>, E>)
+  explicit none(Wrapped obj) noexcept(insitu<Wrapped>())
+    : none{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {}
   ~none() {
     vptr_->op_(data_, nullptr);
   }
@@ -5951,40 +6058,40 @@ inline auto make_none() -> none<> {
   return {};
 }
 PUSHMI_TEMPLATE(class EF)
-  (requires PUSHMI_BROKEN_SUBSUMPTION(not lazy::Receiver<EF> && not lazy::Invocable<EF&>))
+  (requires PUSHMI_BROKEN_SUBSUMPTION(not defer::Receiver<EF> && not defer::Invocable<EF&>))
 auto make_none(EF ef) -> none<EF, ignoreDF> {
   return none<EF, ignoreDF>{std::move(ef)};
 }
 PUSHMI_TEMPLATE(class DF)
-  (requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<DF>))
+  (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<DF>))
 auto make_none(DF df) -> none<abortEF, DF> {
   return none<abortEF, DF>{std::move(df)};
 }
 PUSHMI_TEMPLATE(class EF, class DF)
-  (requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<EF>))
+  (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<EF>))
 auto make_none(EF ef, DF df) -> none<EF, DF> {
   return {std::move(ef), std::move(df)};
 }
 PUSHMI_TEMPLATE(class Data)
-  (requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>>)
+  (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>>)
 auto make_none(Data d) -> none<Data, passDEF, passDDF> {
   return none<Data, passDEF, passDDF>{std::move(d)};
 }
 PUSHMI_TEMPLATE(class Data, class DEF)
-  (requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>>
-    PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Invocable<DEF&, Data&>))
+  (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>>
+    PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Invocable<DEF&, Data&>))
 auto make_none(Data d, DEF ef) -> none<Data, DEF, passDDF> {
   return {std::move(d), std::move(ef)};
 }
 PUSHMI_TEMPLATE(class Data, class DDF)
-  (requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>> &&
-    lazy::Invocable<DDF&, Data&>)
+  (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>> &&
+    defer::Invocable<DDF&, Data&>)
 auto make_none(Data d, DDF df) -> none<Data, passDEF, DDF> {
   return {std::move(d), std::move(df)};
 }
 PUSHMI_TEMPLATE(class Data, class DEF, class DDF)
-  (requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>> &&
-    lazy::Invocable<DDF&, Data&>)
+  (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>> &&
+    defer::Invocable<DDF&, Data&>)
 auto make_none(Data d, DEF ef, DDF df) -> none<Data, DEF, DDF> {
   return {std::move(d), std::move(ef), std::move(df)};
 }
@@ -5995,34 +6102,34 @@ auto make_none(Data d, DEF ef, DDF df) -> none<Data, DEF, DDF> {
 none() -> none<>;
 
 PUSHMI_TEMPLATE(class EF)
-  (requires PUSHMI_BROKEN_SUBSUMPTION(not lazy::Receiver<EF> && not lazy::Invocable<EF&>))
+  (requires PUSHMI_BROKEN_SUBSUMPTION(not defer::Receiver<EF> && not defer::Invocable<EF&>))
 none(EF) -> none<EF, ignoreDF>;
 
 PUSHMI_TEMPLATE(class DF)
-  (requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<DF>))
+  (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<DF>))
 none(DF) -> none<abortEF, DF>;
 
 PUSHMI_TEMPLATE(class EF, class DF)
-  (requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<EF>))
+  (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<EF>))
 none(EF, DF) -> none<EF, DF>;
 
 PUSHMI_TEMPLATE(class Data)
-  (requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>>)
+  (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>>)
 none(Data) -> none<Data, passDEF, passDDF>;
 
 PUSHMI_TEMPLATE(class Data, class DEF)
-  (requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>>
-    PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Invocable<DEF&, Data&>))
+  (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>>
+    PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Invocable<DEF&, Data&>))
 none(Data, DEF) -> none<Data, DEF, passDDF>;
 
 PUSHMI_TEMPLATE(class Data, class DDF)
-  (requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>> &&
-    lazy::Invocable<DDF&, Data&>)
+  (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>> &&
+    defer::Invocable<DDF&, Data&>)
 none(Data, DDF) -> none<Data, passDEF, DDF>;
 
 PUSHMI_TEMPLATE(class Data, class DEF, class DDF)
-  (requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>> &&
-    lazy::Invocable<DDF&, Data&>)
+  (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>> &&
+    defer::Invocable<DDF&, Data&>)
 none(Data, DEF, DDF) -> none<Data, DEF, DDF>;
 #endif
 
@@ -6092,21 +6199,8 @@ class deferred<detail::erase_deferred_t, E> {
     void (*submit_)(data&, any_none<E>) = s_submit;
     static constexpr vtable const noop_{};
   } const* vptr_ = &vtable::noop_;
-  template <class T, class U = std::decay_t<T>>
-  using wrapped_t =
-    std::enable_if_t<!std::is_same<U, deferred>::value, U>;
- public:
-  using properties = property_set<is_sender<>, is_none<>>;
-
-  deferred() = default;
-  deferred(deferred&& that) noexcept : deferred() {
-    that.vptr_->op_(that.data_, &data_);
-    std::swap(that.vptr_, vptr_);
-  }
-  PUSHMI_TEMPLATE(class Wrapped)
-    (requires SenderTo<wrapped_t<Wrapped>, any_none<E>, is_none<>>
-      PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
-  explicit deferred(Wrapped obj) : deferred() {
+  template <class Wrapped>
+  deferred(Wrapped obj, std::false_type) : deferred() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -6121,10 +6215,8 @@ class deferred<detail::erase_deferred_t, E> {
     data_.pobj_ = new Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
-  PUSHMI_TEMPLATE(class Wrapped)
-    (requires SenderTo<wrapped_t<Wrapped>, any_none<E>, is_none<>>
-      && insitu<Wrapped>())
-  explicit deferred(Wrapped obj) noexcept : deferred() {
+  template <class Wrapped>
+  deferred(Wrapped obj, std::true_type) noexcept : deferred() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -6141,6 +6233,21 @@ class deferred<detail::erase_deferred_t, E> {
     new (data_.buffer_) Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
+  template <class T, class U = std::decay_t<T>>
+  using wrapped_t =
+    std::enable_if_t<!std::is_same<U, deferred>::value, U>;
+ public:
+  using properties = property_set<is_sender<>, is_none<>>;
+
+  deferred() = default;
+  deferred(deferred&& that) noexcept : deferred() {
+    that.vptr_->op_(that.data_, &data_);
+    std::swap(that.vptr_, vptr_);
+  }
+  PUSHMI_TEMPLATE(class Wrapped)
+    (requires SenderTo<wrapped_t<Wrapped>, any_none<E>, is_none<>>)
+  explicit deferred(Wrapped obj) noexcept(insitu<Wrapped>())
+    : deferred{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {}
   ~deferred() {
     vptr_->op_(data_, nullptr);
   }
@@ -6271,7 +6378,7 @@ class single<V, E> {
     char buffer_[sizeof(std::promise<int>)]; // can hold a std::promise in-situ
   } data_{};
   template <class Wrapped>
-  static constexpr bool insitu() {
+  static constexpr bool insitu() noexcept {
     return sizeof(Wrapped) <= sizeof(data::buffer_) &&
         std::is_nothrow_move_constructible<Wrapped>::value;
   }
@@ -6300,19 +6407,8 @@ class single<V, E> {
     static_assert(NothrowInvocable<decltype(::pushmi::set_error), Wrapped, E>,
       "Wrapped single must support E and be noexcept");
   }
-public:
-  using properties = property_set<is_receiver<>, is_single<>>;
-
-  single() = default;
-  single(single&& that) noexcept : single() {
-    that.vptr_->op_(that.data_, &data_);
-    std::swap(that.vptr_, vptr_);
-  }
-  PUSHMI_TEMPLATE(class Wrapped)
-    (requires SingleReceiver<wrapped_t<Wrapped>, V, E>
-      PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
-  explicit single(Wrapped obj) : single() {
-    check<Wrapped>();
+  template<class Wrapped>
+  single(Wrapped obj, std::false_type) : single() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -6336,10 +6432,8 @@ public:
     data_.pobj_ = new Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
-  PUSHMI_TEMPLATE(class Wrapped)
-    (requires SingleReceiver<wrapped_t<Wrapped>, V, E> && insitu<Wrapped>())
-  explicit single(Wrapped obj) noexcept : single() {
-    check<Wrapped>();
+  template<class Wrapped>
+  single(Wrapped obj, std::true_type) noexcept : single() {
     struct s {
       static void op(data& src, data* dst) {
           if (dst)
@@ -6366,6 +6460,20 @@ public:
     new ((void*)data_.buffer_) Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
+public:
+  using properties = property_set<is_receiver<>, is_single<>>;
+
+  single() = default;
+  single(single&& that) noexcept : single() {
+    that.vptr_->op_(that.data_, &data_);
+    std::swap(that.vptr_, vptr_);
+  }
+  PUSHMI_TEMPLATE(class Wrapped)
+    (requires SingleReceiver<wrapped_t<Wrapped>, V, E>)
+  explicit single(Wrapped obj) noexcept(insitu<Wrapped>())
+    : single{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {
+    check<Wrapped>();
+  }
   ~single() {
     vptr_->op_(data_, nullptr);
   }
@@ -6535,7 +6643,7 @@ inline auto make_single() -> single<> {
   return {};
 }
 PUSHMI_TEMPLATE(class VF)
-  (requires PUSHMI_BROKEN_SUBSUMPTION(not lazy::Receiver<VF> && not lazy::Invocable<VF&>))
+  (requires PUSHMI_BROKEN_SUBSUMPTION(not defer::Receiver<VF> && not defer::Invocable<VF&>))
 auto make_single(VF vf) -> single<VF, abortEF, ignoreDF> {
   return single<VF, abortEF, ignoreDF>{std::move(vf)};
 }
@@ -6544,58 +6652,58 @@ auto make_single(on_error_fn<EFN...> ef) -> single<ignoreVF, on_error_fn<EFN...>
   return single<ignoreVF, on_error_fn<EFN...>, ignoreDF>{std::move(ef)};
 }
 PUSHMI_TEMPLATE(class DF)
-  (requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<DF>))
+  (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<DF>))
 auto make_single(DF df) -> single<ignoreVF, abortEF, DF> {
   return single<ignoreVF, abortEF, DF>{std::move(df)};
 }
 PUSHMI_TEMPLATE(class VF, class EF)
-  (requires PUSHMI_BROKEN_SUBSUMPTION(not lazy::Receiver<VF> && not lazy::Invocable<EF&>))
+  (requires PUSHMI_BROKEN_SUBSUMPTION(not defer::Receiver<VF> && not defer::Invocable<EF&>))
 auto make_single(VF vf, EF ef) -> single<VF, EF, ignoreDF> {
   return {std::move(vf), std::move(ef)};
 }
 PUSHMI_TEMPLATE(class EF, class DF)
-  (requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<EF>))
+  (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<EF>))
 auto make_single(EF ef, DF df) -> single<ignoreVF, EF, DF> {
   return {std::move(ef), std::move(df)};
 }
 PUSHMI_TEMPLATE(class VF, class EF, class DF)
-  (requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<VF>))
+  (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<VF>))
 auto make_single(VF vf, EF ef, DF df) -> single<VF, EF, DF> {
   return {std::move(vf), std::move(ef), std::move(df)};
 }
 PUSHMI_TEMPLATE(class Data)
-  (requires lazy::Receiver<Data, is_single<>>)
+  (requires defer::Receiver<Data, is_single<>>)
 auto make_single(Data d) -> single<Data, passDVF, passDEF, passDDF> {
   return single<Data, passDVF, passDEF, passDDF>{std::move(d)};
 }
 PUSHMI_TEMPLATE(class Data, class DVF)
-  (requires lazy::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Invocable<DVF&, Data&>))
+  (requires defer::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Invocable<DVF&, Data&>))
 auto make_single(Data d, DVF vf) -> single<Data, DVF, passDEF, passDDF> {
   return {std::move(d), std::move(vf)};
 }
 PUSHMI_TEMPLATE(class Data, class... DEFN)
-  (requires lazy::Receiver<Data, is_single<>>)
+  (requires defer::Receiver<Data, is_single<>>)
 auto make_single(Data d, on_error_fn<DEFN...> ef) ->
     single<Data, passDVF, on_error_fn<DEFN...>, passDDF> {
   return {std::move(d), std::move(ef)};
 }
 PUSHMI_TEMPLATE(class Data, class DDF)
-  (requires lazy::Receiver<Data, is_single<>> && lazy::Invocable<DDF&, Data&>)
+  (requires defer::Receiver<Data, is_single<>> && defer::Invocable<DDF&, Data&>)
 auto make_single(Data d, DDF df) -> single<Data, passDVF, passDEF, DDF> {
   return {std::move(d), std::move(df)};
 }
 PUSHMI_TEMPLATE(class Data, class DVF, class DEF)
-  (requires lazy::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Invocable<DEF&, Data&>))
+  (requires defer::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Invocable<DEF&, Data&>))
 auto make_single(Data d, DVF vf, DEF ef) -> single<Data, DVF, DEF, passDDF> {
   return {std::move(d), std::move(vf), std::move(ef)};
 }
 PUSHMI_TEMPLATE(class Data, class DEF, class DDF)
-  (requires lazy::Receiver<Data, is_single<>> && lazy::Invocable<DDF&, Data&>)
+  (requires defer::Receiver<Data, is_single<>> && defer::Invocable<DDF&, Data&>)
 auto make_single(Data d, DEF ef, DDF df) -> single<Data, passDVF, DEF, DDF> {
   return {std::move(d), std::move(ef), std::move(df)};
 }
 PUSHMI_TEMPLATE(class Data, class DVF, class DEF, class DDF)
-  (requires lazy::Receiver<Data, is_single<>> && lazy::Invocable<DDF&, Data&>)
+  (requires defer::Receiver<Data, is_single<>> && defer::Invocable<DDF&, Data&>)
 auto make_single(Data d, DVF vf, DEF ef, DDF df) -> single<Data, DVF, DEF, DDF> {
   return {std::move(d), std::move(vf), std::move(ef), std::move(df)};
 }
@@ -6606,55 +6714,55 @@ auto make_single(Data d, DVF vf, DEF ef, DDF df) -> single<Data, DVF, DEF, DDF>
 single() -> single<>;
 
 PUSHMI_TEMPLATE(class VF)
-  (requires PUSHMI_BROKEN_SUBSUMPTION(not lazy::Receiver<VF> && not lazy::Invocable<VF&>))
+  (requires PUSHMI_BROKEN_SUBSUMPTION(not defer::Receiver<VF> && not defer::Invocable<VF&>))
 single(VF) -> single<VF, abortEF, ignoreDF>;
 
 template <class... EFN>
 single(on_error_fn<EFN...>) -> single<ignoreVF, on_error_fn<EFN...>, ignoreDF>;
 
 PUSHMI_TEMPLATE(class DF)
-  (requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<DF>))
+  (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<DF>))
 single(DF) -> single<ignoreVF, abortEF, DF>;
 
 PUSHMI_TEMPLATE(class VF, class EF)
-  (requires PUSHMI_BROKEN_SUBSUMPTION(not lazy::Receiver<VF> && not lazy::Invocable<EF&>))
+  (requires PUSHMI_BROKEN_SUBSUMPTION(not defer::Receiver<VF> && not defer::Invocable<EF&>))
 single(VF, EF) -> single<VF, EF, ignoreDF>;
 
 PUSHMI_TEMPLATE(class EF, class DF)
-  (requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<EF>))
+  (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<EF>))
 single(EF, DF) -> single<ignoreVF, EF, DF>;
 
 PUSHMI_TEMPLATE(class VF, class EF, class DF)
-  (requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<VF>))
+  (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<VF>))
 single(VF, EF, DF) -> single<VF, EF, DF>;
 
 PUSHMI_TEMPLATE(class Data)
-  (requires lazy::Receiver<Data, is_single<>>)
+  (requires defer::Receiver<Data, is_single<>>)
 single(Data d) -> single<Data, passDVF, passDEF, passDDF>;
 
 PUSHMI_TEMPLATE(class Data, class DVF)
-  (requires lazy::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Invocable<DVF&, Data&>))
+  (requires defer::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Invocable<DVF&, Data&>))
 single(Data d, DVF vf) -> single<Data, DVF, passDEF, passDDF>;
 
 PUSHMI_TEMPLATE(class Data, class... DEFN)
-  (requires lazy::Receiver<Data, is_single<>>)
+  (requires defer::Receiver<Data, is_single<>>)
 single(Data d, on_error_fn<DEFN...>) ->
     single<Data, passDVF, on_error_fn<DEFN...>, passDDF>;
 
 PUSHMI_TEMPLATE(class Data, class DDF)
-  (requires lazy::Receiver<Data, is_single<>> && lazy::Invocable<DDF&, Data&>)
+  (requires defer::Receiver<Data, is_single<>> && defer::Invocable<DDF&, Data&>)
 single(Data d, DDF) -> single<Data, passDVF, passDEF, DDF>;
 
 PUSHMI_TEMPLATE(class Data, class DVF, class DEF)
-  (requires lazy::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Invocable<DEF&, Data&>))
+  (requires defer::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Invocable<DEF&, Data&>))
 single(Data d, DVF vf, DEF ef) -> single<Data, DVF, DEF, passDDF>;
 
 PUSHMI_TEMPLATE(class Data, class DEF, class DDF)
-  (requires lazy::Receiver<Data, is_single<>> && lazy::Invocable<DDF&, Data&>)
+  (requires defer::Receiver<Data, is_single<>> && defer::Invocable<DDF&, Data&>)
 single(Data d, DEF, DDF) -> single<Data, passDVF, DEF, DDF>;
 
 PUSHMI_TEMPLATE(class Data, class DVF, class DEF, class DDF)
-  (requires lazy::Receiver<Data, is_single<>> && lazy::Invocable<DDF&, Data&>)
+  (requires defer::Receiver<Data, is_single<>> && defer::Invocable<DDF&, Data&>)
 single(Data d, DVF vf, DEF ef, DDF df) -> single<Data, DVF, DEF, DDF>;
 #endif
 
@@ -6713,22 +6821,8 @@ class any_single_deferred {
     void (*submit_)(data&, single<V, E>) = s_submit;
     static constexpr vtable const noop_ {};
   } const* vptr_ = &vtable::noop_;
-  template <class T, class U = std::decay_t<T>>
-  using wrapped_t =
-    std::enable_if_t<!std::is_same<U, any_single_deferred>::value, U>;
- public:
-  using properties = property_set<is_sender<>, is_single<>>;
-
-  any_single_deferred() = default;
-  any_single_deferred(any_single_deferred&& that) noexcept : any_single_deferred() {
-    that.vptr_->op_(that.data_, &data_);
-    std::swap(that.vptr_, vptr_);
-  }
-
-  PUSHMI_TEMPLATE(class Wrapped)
-    (requires SenderTo<wrapped_t<Wrapped>, single<V, E>, is_single<>>
-      PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
-  explicit any_single_deferred(Wrapped obj) : any_single_deferred() {
+  template <class Wrapped>
+  any_single_deferred(Wrapped obj, std::false_type) : any_single_deferred() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -6743,10 +6837,9 @@ class any_single_deferred {
     data_.pobj_ = new Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
-  PUSHMI_TEMPLATE(class Wrapped)
-    (requires SenderTo<wrapped_t<Wrapped>, single<V, E>, is_single<>>
-      && insitu<Wrapped>())
-  explicit any_single_deferred(Wrapped obj) noexcept : any_single_deferred() {
+  template <class Wrapped>
+  any_single_deferred(Wrapped obj, std::true_type) noexcept
+      : any_single_deferred() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -6763,6 +6856,23 @@ class any_single_deferred {
     new (data_.buffer_) Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
+  template <class T, class U = std::decay_t<T>>
+  using wrapped_t =
+    std::enable_if_t<!std::is_same<U, any_single_deferred>::value, U>;
+ public:
+  using properties = property_set<is_sender<>, is_single<>>;
+
+  any_single_deferred() = default;
+  any_single_deferred(any_single_deferred&& that) noexcept
+      : any_single_deferred() {
+    that.vptr_->op_(that.data_, &data_);
+    std::swap(that.vptr_, vptr_);
+  }
+
+  PUSHMI_TEMPLATE(class Wrapped)
+    (requires SenderTo<wrapped_t<Wrapped>, single<V, E>, is_single<>>)
+  explicit any_single_deferred(Wrapped obj) noexcept(insitu<Wrapped>())
+    : any_single_deferred{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {}
   ~any_single_deferred() {
     vptr_->op_(data_, nullptr);
   }
@@ -6793,7 +6903,7 @@ class single_deferred<SF> {
       : sf_(std::move(sf)) {}
 
   PUSHMI_TEMPLATE(class Out)
-    (requires lazy::Receiver<Out, is_single<>> && lazy::Invocable<SF&, Out>)
+    (requires defer::Receiver<Out, is_single<>> && defer::Invocable<SF&, Out>)
   void submit(Out out) {
     sf_(std::move(out));
   }
@@ -6814,7 +6924,8 @@ class single_deferred_2 {
   constexpr single_deferred_2(Data data, DSF sf)
       : data_(std::move(data)), sf_(std::move(sf)) {}
   PUSHMI_TEMPLATE(class Out)
-    (requires lazy::Receiver<Out, is_single<>> && lazy::Invocable<DSF&, Data&, Out>)
+    (requires defer::Receiver<Out, is_single<>> &&
+        defer::Invocable<DSF&, Data&, Out>)
   void submit(Out out) {
     sf_(data_, std::move(out));
   }
@@ -6823,7 +6934,7 @@ class single_deferred_2 {
 template <class A, class B>
 using single_deferred_base =
   meta::if_c<
-    Sender<A, is_single<>>,
+    (bool)Sender<A, is_single<>>,
     single_deferred_2<A, B>,
     any_single_deferred<A, B>>;
 } // namespace detail
@@ -6916,23 +7027,9 @@ class any_time_single_deferred {
     void (*submit_)(data&, TP, single<V, E>) = s_submit;
     static constexpr vtable const noop_ = {};
   } const* vptr_ = &vtable::noop_;
-  template <class T, class U = std::decay_t<T>>
-  using wrapped_t =
-    std::enable_if_t<!std::is_same<U, any_time_single_deferred>::value, U>;
-
- public:
-  using properties = property_set<is_time<>, is_single<>>;
-
-  any_time_single_deferred() = default;
-  any_time_single_deferred(any_time_single_deferred&& that) noexcept
-      : any_time_single_deferred() {
-    that.vptr_->op_(that.data_, &data_);
-    std::swap(that.vptr_, vptr_);
-  }
-  PUSHMI_TEMPLATE (class Wrapped)
-    (requires TimeSenderTo<wrapped_t<Wrapped>, single<V, E>>
-      PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
-  explicit any_time_single_deferred(Wrapped obj) : any_time_single_deferred() {
+  template <class Wrapped>
+  any_time_single_deferred(Wrapped obj, std::false_type)
+    : any_time_single_deferred() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -6953,10 +7050,9 @@ class any_time_single_deferred {
     data_.pobj_ = new Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
-  PUSHMI_TEMPLATE (class Wrapped)
-    (requires TimeSenderTo<wrapped_t<Wrapped>, single<V, E>> &&
-      insitu<Wrapped>())
-  explicit any_time_single_deferred(Wrapped obj) noexcept : any_time_single_deferred() {
+  template <class Wrapped>
+  any_time_single_deferred(Wrapped obj, std::true_type) noexcept
+    : any_time_single_deferred() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -6978,6 +7074,24 @@ class any_time_single_deferred {
     new (data_.buffer_) Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
+  template <class T, class U = std::decay_t<T>>
+  using wrapped_t =
+    std::enable_if_t<!std::is_same<U, any_time_single_deferred>::value, U>;
+
+ public:
+  using properties = property_set<is_time<>, is_single<>>;
+
+  any_time_single_deferred() = default;
+  any_time_single_deferred(any_time_single_deferred&& that) noexcept
+      : any_time_single_deferred() {
+    that.vptr_->op_(that.data_, &data_);
+    std::swap(that.vptr_, vptr_);
+  }
+  PUSHMI_TEMPLATE (class Wrapped)
+    (requires TimeSenderTo<wrapped_t<Wrapped>, single<V, E>>)
+  explicit any_time_single_deferred(Wrapped obj) noexcept(insitu<Wrapped>())
+  : any_time_single_deferred{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {
+  }
   ~any_time_single_deferred() {
     vptr_->op_(data_, nullptr);
   }
@@ -7058,7 +7172,7 @@ class time_single_deferred_2 {
 template <class A, class B, class C>
 using time_single_deferred_base =
   meta::if_c<
-    TimeSender<A, is_single<>>,
+    (bool)TimeSender<A, is_single<>>,
     time_single_deferred_2<A, B, C>,
     any_time_single_deferred<A, B, C>>;
 } // namespace detail
@@ -7318,21 +7432,8 @@ class flow_single<V, PE, E> {
     void (*starting_)(data&, any_none<PE>&) = s_starting;
     static constexpr vtable const noop_ {};
   } const* vptr_ = &vtable::noop_;
-  template <class T, class U = std::decay_t<T>>
-  using wrapped_t =
-    std::enable_if_t<!std::is_same<U, flow_single>::value, U>;
-public:
-  using properties = property_set<is_receiver<>, is_flow<>, is_single<>>;
-
-  flow_single() = default;
-  flow_single(flow_single&& that) noexcept : flow_single() {
-    that.vptr_->op_(that.data_, &data_);
-    std::swap(that.vptr_, vptr_);
-  }
-  PUSHMI_TEMPLATE(class Wrapped)
-    (requires FlowSingleReceiver<wrapped_t<Wrapped>, any_none<PE>, V, PE, E>
-      PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
-  explicit flow_single(Wrapped obj) : flow_single() {
+  template <class Wrapped>
+  flow_single(Wrapped obj, std::false_type) : flow_single() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -7359,10 +7460,8 @@ public:
     data_.pobj_ = new Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
-  PUSHMI_TEMPLATE(class Wrapped)
-    (requires FlowSingleReceiver<wrapped_t<Wrapped>, any_none<PE>, V, PE, E>
-      && insitu<Wrapped>())
-  explicit flow_single(Wrapped obj) noexcept : flow_single() {
+  template <class Wrapped>
+  flow_single(Wrapped obj, std::true_type) noexcept : flow_single() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -7392,6 +7491,21 @@ public:
     new (data_.buffer_) Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
+  template <class T, class U = std::decay_t<T>>
+  using wrapped_t =
+    std::enable_if_t<!std::is_same<U, flow_single>::value, U>;
+public:
+  using properties = property_set<is_receiver<>, is_flow<>, is_single<>>;
+
+  flow_single() = default;
+  flow_single(flow_single&& that) noexcept : flow_single() {
+    that.vptr_->op_(that.data_, &data_);
+    std::swap(that.vptr_, vptr_);
+  }
+  PUSHMI_TEMPLATE(class Wrapped)
+    (requires FlowSingleReceiver<wrapped_t<Wrapped>, any_none<PE>, V, PE, E>)
+  explicit flow_single(Wrapped obj) noexcept(insitu<Wrapped>())
+    : flow_single{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {}
   ~flow_single() {
     vptr_->op_(data_, nullptr);
   }
@@ -7884,22 +7998,8 @@ class flow_single_deferred<V, PE, E> {
     void (*submit_)(data&, flow_single<V, PE, E>) = s_submit;
     static constexpr vtable const noop_ {};
   } const* vptr_ = &vtable::noop_;
-  template <class T, class U = std::decay_t<T>>
-  using wrapped_t =
-    std::enable_if_t<!std::is_same<U, flow_single_deferred>::value, U>;
- public:
-  using properties = property_set<is_sender<>, is_flow<>, is_single<>>;
-
-  flow_single_deferred() = default;
-  flow_single_deferred(flow_single_deferred&& that) noexcept
-      : flow_single_deferred() {
-    that.vptr_->op_(that.data_, &data_);
-    std::swap(that.vptr_, vptr_);
-  }
-  PUSHMI_TEMPLATE (class Wrapped)
-    (requires FlowSender<wrapped_t<Wrapped>, is_single<>>
-      PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
-  explicit flow_single_deferred(Wrapped obj) : flow_single_deferred() {
+  template <class Wrapped>
+  flow_single_deferred(Wrapped obj, std::false_type) : flow_single_deferred() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -7914,9 +8014,9 @@ class flow_single_deferred<V, PE, E> {
     data_.pobj_ = new Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
-  PUSHMI_TEMPLATE (class Wrapped)
-    (requires FlowSender<wrapped_t<Wrapped>, is_single<>> && insitu<Wrapped>())
-  explicit flow_single_deferred(Wrapped obj) noexcept : flow_single_deferred() {
+  template <class Wrapped>
+  flow_single_deferred(Wrapped obj, std::true_type) noexcept
+    : flow_single_deferred() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -7934,6 +8034,22 @@ class flow_single_deferred<V, PE, E> {
     new (data_.buffer_) Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
+  template <class T, class U = std::decay_t<T>>
+  using wrapped_t =
+    std::enable_if_t<!std::is_same<U, flow_single_deferred>::value, U>;
+ public:
+  using properties = property_set<is_sender<>, is_flow<>, is_single<>>;
+
+  flow_single_deferred() = default;
+  flow_single_deferred(flow_single_deferred&& that) noexcept
+      : flow_single_deferred() {
+    that.vptr_->op_(that.data_, &data_);
+    std::swap(that.vptr_, vptr_);
+  }
+  PUSHMI_TEMPLATE (class Wrapped)
+    (requires FlowSender<wrapped_t<Wrapped>, is_single<>>)
+  explicit flow_single_deferred(Wrapped obj) noexcept(insitu<Wrapped>())
+    : flow_single_deferred{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {}
   ~flow_single_deferred() {
     vptr_->op_(data_, nullptr);
   }
@@ -8981,6 +9097,7 @@ auto just(V v) {
 // LICENSE file in the root directory of this source tree.
 
 //#include "../single.h"
+//#include "../single_deferred.h"
 //#include "submit.h"
 //#include "extension_operators.h"
 
diff --git a/folly/experimental/pushmi/include/pushmi/concepts.h b/folly/experimental/pushmi/include/pushmi/concepts.h
index 041644e51..6ba6718e5 100644
--- a/folly/experimental/pushmi/include/pushmi/concepts.h
+++ b/folly/experimental/pushmi/include/pushmi/concepts.h
@@ -350,9 +350,9 @@ PUSHMI_CONCEPT_DEF(
 );
 
 template <class D>
-using time_point_t =
-  std::enable_if_t<TimeSender<D>, decltype(::pushmi::now(std::declval<D&>()))>;
-
+PUSHMI_PP_CONSTRAINED_USING(
+  TimeSender<D>,
+  time_point_t =, decltype(::pushmi::now(std::declval<D&>())));
 
 // this is a more general form where the constraint could be time or priority
 // enum or any other ordering constraint value-type.
@@ -386,9 +386,8 @@ PUSHMI_CONCEPT_DEF(
 );
 
 template <class D>
-using constraint_t =
-  std::enable_if_t<
-    ConstrainedSender<D>,
-    decltype(::pushmi::top(std::declval<D&>()))>;
+PUSHMI_PP_CONSTRAINED_USING(
+  ConstrainedSender<D>,
+  constraint_t =, decltype(::pushmi::top(std::declval<D&>())));
 
 } // namespace pushmi
diff --git a/folly/experimental/pushmi/include/pushmi/deferred.h b/folly/experimental/pushmi/include/pushmi/deferred.h
index 7f825893f..0842b516c 100644
--- a/folly/experimental/pushmi/include/pushmi/deferred.h
+++ b/folly/experimental/pushmi/include/pushmi/deferred.h
@@ -29,21 +29,8 @@ class deferred<detail::erase_deferred_t, E> {
     void (*submit_)(data&, any_none<E>) = s_submit;
     static constexpr vtable const noop_{};
   } const* vptr_ = &vtable::noop_;
-  template <class T, class U = std::decay_t<T>>
-  using wrapped_t =
-    std::enable_if_t<!std::is_same<U, deferred>::value, U>;
- public:
-  using properties = property_set<is_sender<>, is_none<>>;
-
-  deferred() = default;
-  deferred(deferred&& that) noexcept : deferred() {
-    that.vptr_->op_(that.data_, &data_);
-    std::swap(that.vptr_, vptr_);
-  }
-  PUSHMI_TEMPLATE(class Wrapped)
-    (requires SenderTo<wrapped_t<Wrapped>, any_none<E>, is_none<>>
-      PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
-  explicit deferred(Wrapped obj) : deferred() {
+  template <class Wrapped>
+  deferred(Wrapped obj, std::false_type) : deferred() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -58,10 +45,8 @@ class deferred<detail::erase_deferred_t, E> {
     data_.pobj_ = new Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
-  PUSHMI_TEMPLATE(class Wrapped)
-    (requires SenderTo<wrapped_t<Wrapped>, any_none<E>, is_none<>>
-      && insitu<Wrapped>())
-  explicit deferred(Wrapped obj) noexcept : deferred() {
+  template <class Wrapped>
+  deferred(Wrapped obj, std::true_type) noexcept : deferred() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -78,6 +63,21 @@ class deferred<detail::erase_deferred_t, E> {
     new (data_.buffer_) Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
+  template <class T, class U = std::decay_t<T>>
+  using wrapped_t =
+    std::enable_if_t<!std::is_same<U, deferred>::value, U>;
+ public:
+  using properties = property_set<is_sender<>, is_none<>>;
+
+  deferred() = default;
+  deferred(deferred&& that) noexcept : deferred() {
+    that.vptr_->op_(that.data_, &data_);
+    std::swap(that.vptr_, vptr_);
+  }
+  PUSHMI_TEMPLATE(class Wrapped)
+    (requires SenderTo<wrapped_t<Wrapped>, any_none<E>, is_none<>>)
+  explicit deferred(Wrapped obj) noexcept(insitu<Wrapped>())
+    : deferred{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {}
   ~deferred() {
     vptr_->op_(data_, nullptr);
   }
diff --git a/folly/experimental/pushmi/include/pushmi/detail/concept_def.h b/folly/experimental/pushmi/include/pushmi/detail/concept_def.h
index 5ee18b81b..fe9d5a516 100644
--- a/folly/experimental/pushmi/include/pushmi/detail/concept_def.h
+++ b/folly/experimental/pushmi/include/pushmi/detail/concept_def.h
@@ -185,33 +185,32 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
 //                 t = (U &&) u,
 //                 ::pushmi::concepts::requires_<Same<decltype(t = (U &&) u), T>>
 //             ) &&
-//             std::is_lvalue_reference<T>{}
+//             std::is_lvalue_reference_v<T>
 //     );
 #define PUSHMI_CONCEPT_DEF(DECL, ...)                                          \
     PUSHMI_PP_EVAL(                                                            \
         PUSHMI_PP_DECL_DEF,                                                    \
         PUSHMI_PP_CAT(PUSHMI_PP_DEF_DECL_, DECL),                              \
-        __VA_ARGS__,                                                           \
-        PUSHMI_PP_EAT)                                                         \
+        __VA_ARGS__)                                                           \
+    /**/
+#define PUSHMI_PP_DECL_DEF_NAME(...)                                           \
+    __VA_ARGS__,                                                               \
     /**/
-#define PUSHMI_PP_DECL_DEF_NAME(...) __VA_ARGS__,
-#define PUSHMI_PP_DECL_DEF(TPARAM, NAME, REQUIRES, ...)                        \
+#define PUSHMI_PP_DECL_DEF(TPARAM, NAME, ...)                                  \
     PUSHMI_PP_CAT(PUSHMI_PP_DECL_DEF_, PUSHMI_PP_IS_PAREN(NAME))(              \
         TPARAM,                                                                \
         NAME,                                                                  \
-        REQUIRES,                                                              \
         __VA_ARGS__)                                                           \
     /**/
 // The defn is of the form:
 //   template(class A, class B = void, class... Rest)
 //   (concept Name)(A, B, Rest...),
 //      // requirements...
-#define PUSHMI_PP_DECL_DEF_1(TPARAM, NAME, REQUIRES, ...)                      \
+#define PUSHMI_PP_DECL_DEF_1(TPARAM, NAME, ...)                                \
     PUSHMI_PP_EVAL4(                                                           \
         PUSHMI_PP_DECL_DEF_IMPL,                                               \
         TPARAM,                                                                \
         PUSHMI_PP_DECL_DEF_NAME NAME,                                          \
-        REQUIRES,                                                              \
         __VA_ARGS__)                                                           \
     /**/
 // The defn is of the form:
@@ -219,12 +218,11 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
 //   concept Name,
 //      // requirements...
 // Compute the template arguments (A, B) from the template introducer.
-#define PUSHMI_PP_DECL_DEF_0(TPARAM, NAME, REQUIRES, ...)                      \
+#define PUSHMI_PP_DECL_DEF_0(TPARAM, NAME, ...)                                \
     PUSHMI_PP_DECL_DEF_IMPL(                                                   \
         TPARAM,                                                                \
         NAME,                                                                  \
         (PUSHMI_PP_CAT(PUSHMI_PP_AUX_, TPARAM)),                               \
-        REQUIRES,                                                              \
         __VA_ARGS__)                                                           \
     /**/
 // Expand the template definition into a struct and template alias like:
@@ -240,17 +238,83 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
 //    };
 //    template<class A, class B>
 //    inline constexpr bool Name = NameConcept::is_satisfied_by<A, B>(0);
-#define PUSHMI_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, REQUIRES, ...)             \
+#if __cpp_concepts
+// No requires expression
+#define PUSHMI_PP_DEF_IMPL_0(...)                                              \
+    __VA_ARGS__                                                                \
+    /**/
+// Requires expression
+#define PUSHMI_PP_DEF_IMPL_1(...)                                              \
+    PUSHMI_PP_CAT(PUSHMI_PP_DEF_IMPL_1_, __VA_ARGS__)                          \
+    /**/
+#define PUSHMI_PP_DEF_IMPL_1_requires                                          \
+    requires PUSHMI_PP_DEF_IMPL_1_REQUIRES                                     \
+    /**/
+#define PUSHMI_PP_DEF_IMPL_1_REQUIRES(...)                                     \
+    (__VA_ARGS__) PUSHMI_PP_DEF_IMPL_1_REQUIRES_BODY                           \
+    /**/
+#define PUSHMI_PP_DEF_IMPL_1_REQUIRES_BODY(...)                                \
+    { __VA_ARGS__; }                                                           \
+    /**/
+#define PUSHMI_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, ...)                       \
+    inline namespace pushmi_concept_eager {                                    \
+        PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM)                                  \
+        concept bool PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME) = PUSHMI_PP_EVAL2(    \
+            PUSHMI_PP_DEF_IMPL(__VA_ARGS__),                                   \
+            __VA_ARGS__);                                                      \
+    }                                                                          \
+    namespace defer = pushmi_concept_eager;                                    \
+    namespace lazy {                                                           \
+        PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM)                                  \
+        struct PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) {   \
+            using Concept =                                                    \
+                PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept);   \
+            explicit constexpr operator bool() const noexcept {                \
+                return (bool) defer::PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME)<      \
+                    PUSHMI_PP_EXPAND ARGS>;                                    \
+            }                                                                  \
+            constexpr auto operator!() const noexcept {                        \
+                return ::pushmi::concepts::detail::Not<Concept>{};             \
+            }                                                                  \
+            template <class That>                                              \
+            constexpr auto operator&&(That) const noexcept {                   \
+                return ::pushmi::concepts::detail::And<Concept, That>{};       \
+            }                                                                  \
+        };                                                                     \
+        PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM)                                  \
+        PUSHMI_INLINE_VAR constexpr auto PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME) = \
+            PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept)        \
+                <PUSHMI_PP_EXPAND ARGS>{};                                     \
+    }                                                                          \
+    /**/
+#else
+// No requires expression:
+#define PUSHMI_PP_DEF_IMPL_0(...)                                              \
+    () -> std::enable_if_t<bool(__VA_ARGS__), int>                             \
+    /**/
+// Requires expression:
+#define PUSHMI_PP_DEF_IMPL_1(...)                                              \
+    PUSHMI_PP_CAT(PUSHMI_PP_DEF_IMPL_1_, __VA_ARGS__) ), int>                  \
+    /**/
+#define PUSHMI_PP_DEF_IMPL_1_requires                                          \
+    PUSHMI_PP_DEF_IMPL_1_REQUIRES                                              \
+    /**/
+#define PUSHMI_PP_DEF_IMPL_1_REQUIRES(...)                                     \
+    (__VA_ARGS__) -> std::enable_if_t<bool(                                    \
+        ::pushmi::concepts::detail::requires_  PUSHMI_PP_DEF_REQUIRES_BODY     \
+    /**/
+ #define PUSHMI_PP_DEF_REQUIRES_BODY(...)                                      \
+    <decltype(__VA_ARGS__, void())>()                                          \
+    /**/
+#define PUSHMI_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, ...)                       \
     struct PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) {       \
         using Concept =                                                        \
             PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept);       \
         PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN                                    \
         PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM)                                  \
         static auto _concept_requires_ PUSHMI_PP_EVAL2(                        \
-            PUSHMI_PP_DEF_WRAP,                                                \
-            PUSHMI_PP_CAT(PUSHMI_PP_DEF_, REQUIRES),                           \
-            REQUIRES,                                                          \
-            (__VA_ARGS__))(~) int>;                                            \
+            PUSHMI_PP_DEF_IMPL(__VA_ARGS__),                                   \
+            __VA_ARGS__);                                                      \
         PUSHMI_PP_IGNORE_CXX2A_COMPAT_END                                      \
         PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM)                                  \
         struct _is_satisfied_by_ {                                             \
@@ -282,8 +346,18 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
             PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept)        \
                 ::_is_satisfied_by_<PUSHMI_PP_EXPAND ARGS>{};                  \
     }                                                                          \
+    namespace defer = lazy;                                                    \
     /**/
+#endif
 
+#define PUSHMI_PP_REQUIRES_PROBE_requires                                      \
+    PUSHMI_PP_PROBE(~)                                                         \
+    /**/
+#define PUSHMI_PP_DEF_IMPL(REQUIRES, ...)                                      \
+    PUSHMI_PP_CAT(                                                             \
+        PUSHMI_PP_DEF_IMPL_,                                                   \
+        PUSHMI_PP_CHECK(PUSHMI_PP_CAT(PUSHMI_PP_REQUIRES_PROBE_, REQUIRES)))   \
+    /**/
 #define PUSHMI_PP_DEF_DECL_template(...)                                       \
     template(__VA_ARGS__),                                                     \
     /**/
@@ -297,7 +371,6 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
 #define PUSHMI_PP_DEF_bool
 #define PUSHMI_PP_DEF_size_t
 #define PUSHMI_PP_DEF_unsigned
-#define PUSHMI_PP_DEF_requires ~,
 #define PUSHMI_PP_AUX_template(...)                                            \
     PUSHMI_PP_CAT2(                                                            \
         PUSHMI_PP_TPARAM_,                                                     \
@@ -314,63 +387,95 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
 #define PUSHMI_PP_TPARAM_5(_1, ...)                                            \
     PUSHMI_PP_CAT2(PUSHMI_PP_DEF_, _1), PUSHMI_PP_TPARAM_4(__VA_ARGS__)
 
-#define PUSHMI_PP_DEF_WRAP(X, Y, ...)                                          \
-    PUSHMI_PP_EVAL3(                                                           \
-        PUSHMI_PP_CAT(PUSHMI_PP_DEF_WRAP_, PUSHMI_PP_COUNT(__VA_ARGS__)),      \
-        X,                                                                     \
-        Y,                                                                     \
-        __VA_ARGS__)                                                           \
+////////////////////////////////////////////////////////////////////////////////
+// PUSHMI_TEMPLATE
+// Usage:
+//   PUSHMI_TEMPLATE (class A, class B)
+//     (requires Concept1<A> && Concept2<B>)
+//   void foo(A a, B b)
+//   {}
+// or
+//   PUSHMI_TEMPLATE (class A, class B)
+//     (requires requires (expr1, expr2, expr3) && Concept1<A> && Concept2<B>)
+//   void foo(A a, B b)
+//   {}
+#if __cpp_concepts
+#define PUSHMI_TEMPLATE(...)                                                   \
+    template<__VA_ARGS__> PUSHMI_TEMPLATE_AUX_                                 \
     /**/
-
-// No requires expression:
-#define PUSHMI_PP_DEF_WRAP_1(_, HEAD, TAIL)                                    \
-    () -> std::enable_if_t<HEAD, PUSHMI_PP_EXPAND TAIL                         \
+#define PUSHMI_TEMPLATE_AUX_(...)                                              \
+    PUSHMI_TEMPLATE_AUX_4(PUSHMI_PP_CAT(PUSHMI_TEMPLATE_AUX_3_, __VA_ARGS__))  \
     /**/
-// Requires expression:
-#define PUSHMI_PP_DEF_WRAP_2(_a, HEAD, _b, TAIL)                               \
-    PUSHMI_PP_CAT(PUSHMI_PP_DEF_REQUIRES_, PUSHMI_PP_IS_PAREN(HEAD)) HEAD,     \
-    PUSHMI_PP_EXPAND TAIL                                                      \
+#define PUSHMI_TEMPLATE_AUX_3_requires
+#define PUSHMI_TEMPLATE_AUX_4(...)                                             \
+    PUSHMI_TEMPLATE_AUX_5(__VA_ARGS__)(__VA_ARGS__)                            \
     /**/
-// Requires expression without a requirement parameter list:
-#define PUSHMI_PP_DEF_REQUIRES_0                                               \
-    () -> decltype(::pushmi::concepts::detail::requires_                       \
-        PUSHMI_PP_DEF_REQUIRES_EXPRS                                           \
+#define PUSHMI_TEMPLATE_AUX_5(REQUIRES, ...)                                   \
+    PUSHMI_PP_CAT(                                                             \
+        PUSHMI_TEMPLATE_AUX_5_,                                                \
+        PUSHMI_PP_CHECK(PUSHMI_PP_CAT(PUSHMI_PP_REQUIRES_PROBE_, REQUIRES)))   \
     /**/
-// Requires expression with a requirement parameter list:
-#define PUSHMI_PP_DEF_REQUIRES_1(...)                                          \
-    (__VA_ARGS__) -> std::enable_if_t<::pushmi::concepts::detail::requires_    \
-        PUSHMI_PP_DEF_REQUIRES_EXPRS                                           \
+// No requires expression:
+#define PUSHMI_TEMPLATE_AUX_5_0(...)                                           \
+    requires __VA_ARGS__                                                       \
     /**/
-
-#define  PUSHMI_PP_DEF_REQUIRES_EXPRS(...) \
-    <decltype(__VA_ARGS__, void())>()\
+// Requires expression
+#define PUSHMI_TEMPLATE_AUX_5_1(...)                                           \
+    PUSHMI_PP_CAT(PUSHMI_TEMPLATE_AUX_6_, __VA_ARGS__)                         \
     /**/
-
-#define PUSHMI_TYPE_CONSTRAINT(X) class
-
+#define PUSHMI_TEMPLATE_AUX_6_requires(...)\
+    requires requires { __VA_ARGS__; }
+#else
 #define PUSHMI_TEMPLATE(...)                                                   \
     template<__VA_ARGS__ PUSHMI_TEMPLATE_AUX_
 #define PUSHMI_TEMPLATE_AUX_(...) ,                                            \
-    int (*PUSHMI_PP_CAT(_pushmi_concept_unique_, __LINE__))[PUSHMI_COUNTER] = nullptr,                  \
-    std::enable_if_t<PUSHMI_PP_CAT(_pushmi_concept_unique_, __LINE__) ||                                \
-        bool(PUSHMI_TEMPLATE_AUX_4(PUSHMI_PP_CAT(PUSHMI_TEMPLATE_AUX_3_, __VA_ARGS__))), int> = 0>
+    int (*PUSHMI_PP_CAT(_pushmi_concept_unique_, __LINE__))[                   \
+        PUSHMI_COUNTER] = nullptr,                                             \
+    std::enable_if_t<PUSHMI_PP_CAT(_pushmi_concept_unique_, __LINE__) ||       \
+        bool(PUSHMI_TEMPLATE_AUX_4(PUSHMI_PP_CAT(                              \
+            PUSHMI_TEMPLATE_AUX_3_, __VA_ARGS__))), int> = 0>                  \
+    /**/
 #define PUSHMI_TEMPLATE_AUX_3_requires
-#define PUSHMI_TEMPLATE_AUX_4(...) \
-    PUSHMI_PP_EVAL(\
-        PUSHMI_PP_CAT,\
-        PUSHMI_TEMPLATE_AUX_5_, \
-        PUSHMI_PP_IS_EQUAL(\
-            PUSHMI_PP_EVAL2(PUSHMI_PP_COUNT, PUSHMI_PP_CAT2(PUSHMI_TEMPLATE_AUX_5_, __VA_ARGS__)),\
-            PUSHMI_PP_EVAL2(PUSHMI_PP_COUNT, __VA_ARGS__)))(__VA_ARGS__)
-#define PUSHMI_TEMPLATE_AUX_5_requires ~,
-#define PUSHMI_TEMPLATE_AUX_5_0(...) \
-    PUSHMI_PP_CAT(PUSHMI_TEMPLATE_AUX_6_, __VA_ARGS__)
-#define PUSHMI_TEMPLATE_AUX_5_1(...) \
-    __VA_ARGS__
-#define PUSHMI_TEMPLATE_AUX_6_requires(...)\
-    ::pushmi::concepts::detail::requires_<decltype(__VA_ARGS__)>()
+#define PUSHMI_TEMPLATE_AUX_4(...)                                             \
+    PUSHMI_TEMPLATE_AUX_5(__VA_ARGS__)(__VA_ARGS__)                            \
+    /**/
+#define PUSHMI_TEMPLATE_AUX_5(REQUIRES, ...)                                   \
+    PUSHMI_PP_CAT(                                                             \
+        PUSHMI_TEMPLATE_AUX_5_,                                                \
+        PUSHMI_PP_CHECK(PUSHMI_PP_CAT(PUSHMI_PP_REQUIRES_PROBE_, REQUIRES)))   \
+    /**/
+// No requires expression:
+#define PUSHMI_TEMPLATE_AUX_5_0(...)                                           \
+    __VA_ARGS__                                                                \
+    /**/
+#define PUSHMI_TEMPLATE_AUX_5_1(...)                                           \
+    PUSHMI_PP_CAT(PUSHMI_TEMPLATE_AUX_6_, __VA_ARGS__)                         \
+    /**/
+#define PUSHMI_TEMPLATE_AUX_6_requires(...)                                    \
+    ::pushmi::concepts::detail::requires_<decltype(__VA_ARGS__)>()             \
+    /**/
+#endif
+
 
+#if __cpp_concepts
+#define PUSHMI_BROKEN_SUBSUMPTION(...) __VA_ARGS__ // BUGBUG
+#define PUSHMI_TYPE_CONSTRAINT(...) __VA_ARGS__
+#else
 #define PUSHMI_BROKEN_SUBSUMPTION(...) __VA_ARGS__
+#define PUSHMI_TYPE_CONSTRAINT(...) class
+#endif
+
+
+#if __cpp_concepts
+#define PUSHMI_PP_CONSTRAINED_USING(REQUIRES, NAME, TYPE)                      \
+    requires REQUIRES                                                          \
+  using NAME TYPE;                                                             \
+  /**/
+#else
+#define PUSHMI_PP_CONSTRAINED_USING(REQUIRES, NAME, TYPE)                      \
+  using NAME std::enable_if_t<bool(REQUIRES), TYPE>;                           \
+  /**/
+#endif
 
 namespace pushmi {
 namespace concepts {
diff --git a/folly/experimental/pushmi/include/pushmi/flow_single.h b/folly/experimental/pushmi/include/pushmi/flow_single.h
index 85e0554cf..a6f35d762 100644
--- a/folly/experimental/pushmi/include/pushmi/flow_single.h
+++ b/folly/experimental/pushmi/include/pushmi/flow_single.h
@@ -34,21 +34,8 @@ class flow_single<V, PE, E> {
     void (*starting_)(data&, any_none<PE>&) = s_starting;
     static constexpr vtable const noop_ {};
   } const* vptr_ = &vtable::noop_;
-  template <class T, class U = std::decay_t<T>>
-  using wrapped_t =
-    std::enable_if_t<!std::is_same<U, flow_single>::value, U>;
-public:
-  using properties = property_set<is_receiver<>, is_flow<>, is_single<>>;
-
-  flow_single() = default;
-  flow_single(flow_single&& that) noexcept : flow_single() {
-    that.vptr_->op_(that.data_, &data_);
-    std::swap(that.vptr_, vptr_);
-  }
-  PUSHMI_TEMPLATE(class Wrapped)
-    (requires FlowSingleReceiver<wrapped_t<Wrapped>, any_none<PE>, V, PE, E>
-      PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
-  explicit flow_single(Wrapped obj) : flow_single() {
+  template <class Wrapped>
+  flow_single(Wrapped obj, std::false_type) : flow_single() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -75,10 +62,8 @@ public:
     data_.pobj_ = new Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
-  PUSHMI_TEMPLATE(class Wrapped)
-    (requires FlowSingleReceiver<wrapped_t<Wrapped>, any_none<PE>, V, PE, E>
-      && insitu<Wrapped>())
-  explicit flow_single(Wrapped obj) noexcept : flow_single() {
+  template <class Wrapped>
+  flow_single(Wrapped obj, std::true_type) noexcept : flow_single() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -108,6 +93,21 @@ public:
     new (data_.buffer_) Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
+  template <class T, class U = std::decay_t<T>>
+  using wrapped_t =
+    std::enable_if_t<!std::is_same<U, flow_single>::value, U>;
+public:
+  using properties = property_set<is_receiver<>, is_flow<>, is_single<>>;
+
+  flow_single() = default;
+  flow_single(flow_single&& that) noexcept : flow_single() {
+    that.vptr_->op_(that.data_, &data_);
+    std::swap(that.vptr_, vptr_);
+  }
+  PUSHMI_TEMPLATE(class Wrapped)
+    (requires FlowSingleReceiver<wrapped_t<Wrapped>, any_none<PE>, V, PE, E>)
+  explicit flow_single(Wrapped obj) noexcept(insitu<Wrapped>())
+    : flow_single{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {}
   ~flow_single() {
     vptr_->op_(data_, nullptr);
   }
diff --git a/folly/experimental/pushmi/include/pushmi/flow_single_deferred.h b/folly/experimental/pushmi/include/pushmi/flow_single_deferred.h
index c77fb1d9f..511d422d1 100644
--- a/folly/experimental/pushmi/include/pushmi/flow_single_deferred.h
+++ b/folly/experimental/pushmi/include/pushmi/flow_single_deferred.h
@@ -26,22 +26,8 @@ class flow_single_deferred<V, PE, E> {
     void (*submit_)(data&, flow_single<V, PE, E>) = s_submit;
     static constexpr vtable const noop_ {};
   } const* vptr_ = &vtable::noop_;
-  template <class T, class U = std::decay_t<T>>
-  using wrapped_t =
-    std::enable_if_t<!std::is_same<U, flow_single_deferred>::value, U>;
- public:
-  using properties = property_set<is_sender<>, is_flow<>, is_single<>>;
-
-  flow_single_deferred() = default;
-  flow_single_deferred(flow_single_deferred&& that) noexcept
-      : flow_single_deferred() {
-    that.vptr_->op_(that.data_, &data_);
-    std::swap(that.vptr_, vptr_);
-  }
-  PUSHMI_TEMPLATE (class Wrapped)
-    (requires FlowSender<wrapped_t<Wrapped>, is_single<>>
-      PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
-  explicit flow_single_deferred(Wrapped obj) : flow_single_deferred() {
+  template <class Wrapped>
+  flow_single_deferred(Wrapped obj, std::false_type) : flow_single_deferred() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -56,9 +42,9 @@ class flow_single_deferred<V, PE, E> {
     data_.pobj_ = new Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
-  PUSHMI_TEMPLATE (class Wrapped)
-    (requires FlowSender<wrapped_t<Wrapped>, is_single<>> && insitu<Wrapped>())
-  explicit flow_single_deferred(Wrapped obj) noexcept : flow_single_deferred() {
+  template <class Wrapped>
+  flow_single_deferred(Wrapped obj, std::true_type) noexcept
+    : flow_single_deferred() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -76,6 +62,22 @@ class flow_single_deferred<V, PE, E> {
     new (data_.buffer_) Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
+  template <class T, class U = std::decay_t<T>>
+  using wrapped_t =
+    std::enable_if_t<!std::is_same<U, flow_single_deferred>::value, U>;
+ public:
+  using properties = property_set<is_sender<>, is_flow<>, is_single<>>;
+
+  flow_single_deferred() = default;
+  flow_single_deferred(flow_single_deferred&& that) noexcept
+      : flow_single_deferred() {
+    that.vptr_->op_(that.data_, &data_);
+    std::swap(that.vptr_, vptr_);
+  }
+  PUSHMI_TEMPLATE (class Wrapped)
+    (requires FlowSender<wrapped_t<Wrapped>, is_single<>>)
+  explicit flow_single_deferred(Wrapped obj) noexcept(insitu<Wrapped>())
+    : flow_single_deferred{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {}
   ~flow_single_deferred() {
     vptr_->op_(data_, nullptr);
   }
diff --git a/folly/experimental/pushmi/include/pushmi/none.h b/folly/experimental/pushmi/include/pushmi/none.h
index 2267bcfe7..19ccf78f5 100644
--- a/folly/experimental/pushmi/include/pushmi/none.h
+++ b/folly/experimental/pushmi/include/pushmi/none.h
@@ -29,21 +29,8 @@ class none<E> {
     void (*error_)(data&, E) noexcept = s_error;
     static constexpr vtable const noop_ {};
   } const* vptr_ = &vtable::noop_;
-  template <class T, class U = std::decay_t<T>>
-  using wrapped_t =
-    std::enable_if_t<!std::is_same<U, none>::value, U>;
-public:
-  using properties = property_set<is_receiver<>, is_none<>>;
-
-  none() = default;
-  none(none&& that) noexcept : none() {
-    that.vptr_->op_(that.data_, &data_);
-    std::swap(that.vptr_, vptr_);
-  }
-  PUSHMI_TEMPLATE(class Wrapped)
-    (requires NoneReceiver<wrapped_t<Wrapped>, E>
-      PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
-  explicit none(Wrapped obj) : none() {
+  template <class Wrapped>
+  none(Wrapped obj, std::false_type) : none() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -61,9 +48,8 @@ public:
     data_.pobj_ = new Wrapped(std::move(obj));
     vptr_ = &vtable_v;
   }
-  PUSHMI_TEMPLATE(class Wrapped)
-    (requires NoneReceiver<wrapped_t<Wrapped>, E> && insitu<Wrapped>())
-  explicit none(Wrapped obj) noexcept : none() {
+  template <class Wrapped>
+  none(Wrapped obj, std::true_type) noexcept : none() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -83,6 +69,21 @@ public:
     new (data_.buffer_) Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
+  template <class T, class U = std::decay_t<T>>
+  using wrapped_t =
+    std::enable_if_t<!std::is_same<U, none>::value, U>;
+public:
+  using properties = property_set<is_receiver<>, is_none<>>;
+
+  none() = default;
+  none(none&& that) noexcept : none() {
+    that.vptr_->op_(that.data_, &data_);
+    std::swap(that.vptr_, vptr_);
+  }
+  PUSHMI_TEMPLATE(class Wrapped)
+    (requires NoneReceiver<wrapped_t<Wrapped>, E>)
+  explicit none(Wrapped obj) noexcept(insitu<Wrapped>())
+    : none{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {}
   ~none() {
     vptr_->op_(data_, nullptr);
   }
@@ -196,40 +197,40 @@ inline auto make_none() -> none<> {
   return {};
 }
 PUSHMI_TEMPLATE(class EF)
-  (requires PUSHMI_BROKEN_SUBSUMPTION(not lazy::Receiver<EF> && not lazy::Invocable<EF&>))
+  (requires PUSHMI_BROKEN_SUBSUMPTION(not defer::Receiver<EF> && not defer::Invocable<EF&>))
 auto make_none(EF ef) -> none<EF, ignoreDF> {
   return none<EF, ignoreDF>{std::move(ef)};
 }
 PUSHMI_TEMPLATE(class DF)
-  (requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<DF>))
+  (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<DF>))
 auto make_none(DF df) -> none<abortEF, DF> {
   return none<abortEF, DF>{std::move(df)};
 }
 PUSHMI_TEMPLATE(class EF, class DF)
-  (requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<EF>))
+  (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<EF>))
 auto make_none(EF ef, DF df) -> none<EF, DF> {
   return {std::move(ef), std::move(df)};
 }
 PUSHMI_TEMPLATE(class Data)
-  (requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>>)
+  (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>>)
 auto make_none(Data d) -> none<Data, passDEF, passDDF> {
   return none<Data, passDEF, passDDF>{std::move(d)};
 }
 PUSHMI_TEMPLATE(class Data, class DEF)
-  (requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>>
-    PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Invocable<DEF&, Data&>))
+  (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>>
+    PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Invocable<DEF&, Data&>))
 auto make_none(Data d, DEF ef) -> none<Data, DEF, passDDF> {
   return {std::move(d), std::move(ef)};
 }
 PUSHMI_TEMPLATE(class Data, class DDF)
-  (requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>> &&
-    lazy::Invocable<DDF&, Data&>)
+  (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>> &&
+    defer::Invocable<DDF&, Data&>)
 auto make_none(Data d, DDF df) -> none<Data, passDEF, DDF> {
   return {std::move(d), std::move(df)};
 }
 PUSHMI_TEMPLATE(class Data, class DEF, class DDF)
-  (requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>> &&
-    lazy::Invocable<DDF&, Data&>)
+  (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>> &&
+    defer::Invocable<DDF&, Data&>)
 auto make_none(Data d, DEF ef, DDF df) -> none<Data, DEF, DDF> {
   return {std::move(d), std::move(ef), std::move(df)};
 }
@@ -240,34 +241,34 @@ auto make_none(Data d, DEF ef, DDF df) -> none<Data, DEF, DDF> {
 none() -> none<>;
 
 PUSHMI_TEMPLATE(class EF)
-  (requires PUSHMI_BROKEN_SUBSUMPTION(not lazy::Receiver<EF> && not lazy::Invocable<EF&>))
+  (requires PUSHMI_BROKEN_SUBSUMPTION(not defer::Receiver<EF> && not defer::Invocable<EF&>))
 none(EF) -> none<EF, ignoreDF>;
 
 PUSHMI_TEMPLATE(class DF)
-  (requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<DF>))
+  (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<DF>))
 none(DF) -> none<abortEF, DF>;
 
 PUSHMI_TEMPLATE(class EF, class DF)
-  (requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<EF>))
+  (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<EF>))
 none(EF, DF) -> none<EF, DF>;
 
 PUSHMI_TEMPLATE(class Data)
-  (requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>>)
+  (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>>)
 none(Data) -> none<Data, passDEF, passDDF>;
 
 PUSHMI_TEMPLATE(class Data, class DEF)
-  (requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>>
-    PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Invocable<DEF&, Data&>))
+  (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>>
+    PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Invocable<DEF&, Data&>))
 none(Data, DEF) -> none<Data, DEF, passDDF>;
 
 PUSHMI_TEMPLATE(class Data, class DDF)
-  (requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>> &&
-    lazy::Invocable<DDF&, Data&>)
+  (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>> &&
+    defer::Invocable<DDF&, Data&>)
 none(Data, DDF) -> none<Data, passDEF, DDF>;
 
 PUSHMI_TEMPLATE(class Data, class DEF, class DDF)
-  (requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>> &&
-    lazy::Invocable<DDF&, Data&>)
+  (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>> &&
+    defer::Invocable<DDF&, Data&>)
 none(Data, DEF, DDF) -> none<Data, DEF, DDF>;
 #endif
 
diff --git a/folly/experimental/pushmi/include/pushmi/o/defer.h b/folly/experimental/pushmi/include/pushmi/o/defer.h
index f11d06daf..f0c5a78ce 100644
--- a/folly/experimental/pushmi/include/pushmi/o/defer.h
+++ b/folly/experimental/pushmi/include/pushmi/o/defer.h
@@ -7,6 +7,7 @@
 // LICENSE file in the root directory of this source tree.
 
 #include "../single.h"
+#include "../single_deferred.h"
 #include "submit.h"
 #include "extension_operators.h"
 
diff --git a/folly/experimental/pushmi/include/pushmi/properties.h b/folly/experimental/pushmi/include/pushmi/properties.h
index 6f0458a67..5f1abe9f9 100644
--- a/folly/experimental/pushmi/include/pushmi/properties.h
+++ b/folly/experimental/pushmi/include/pushmi/properties.h
@@ -161,14 +161,16 @@ struct property_query_impl :
   meta::and_c<decltype(property_query_fn<ExpectedN>((properties_t<PS>*)nullptr))::value...> {};
 } //namespace detail
 
-template<PUSHMI_TYPE_CONSTRAINT(Properties) PS, PUSHMI_TYPE_CONSTRAINT(Property)... ExpectedN>
+//template<PUSHMI_TYPE_CONSTRAINT(Properties) PS, PUSHMI_TYPE_CONSTRAINT(Property)... ExpectedN>
+template<class PS, class... ExpectedN>
 struct property_query
   : meta::if_c<
       Properties<PS> && And<Property<ExpectedN>...>,
       detail::property_query_impl<PS, ExpectedN...>,
       std::false_type> {};
 
-template<PUSHMI_TYPE_CONSTRAINT(Properties) PS, PUSHMI_TYPE_CONSTRAINT(Property)... ExpectedN>
+//template<PUSHMI_TYPE_CONSTRAINT(Properties) PS, PUSHMI_TYPE_CONSTRAINT(Property)... ExpectedN>
+template<class PS, class... ExpectedN>
 PUSHMI_INLINE_VAR constexpr bool property_query_v = property_query<PS, ExpectedN...>::value;
 
 } // namespace pushmi
diff --git a/folly/experimental/pushmi/include/pushmi/single.h b/folly/experimental/pushmi/include/pushmi/single.h
index dd5b93aa3..7a950580a 100644
--- a/folly/experimental/pushmi/include/pushmi/single.h
+++ b/folly/experimental/pushmi/include/pushmi/single.h
@@ -17,7 +17,7 @@ class single<V, E> {
     char buffer_[sizeof(std::promise<int>)]; // can hold a std::promise in-situ
   } data_{};
   template <class Wrapped>
-  static constexpr bool insitu() {
+  static constexpr bool insitu() noexcept {
     return sizeof(Wrapped) <= sizeof(data::buffer_) &&
         std::is_nothrow_move_constructible<Wrapped>::value;
   }
@@ -46,19 +46,8 @@ class single<V, E> {
     static_assert(NothrowInvocable<decltype(::pushmi::set_error), Wrapped, E>,
       "Wrapped single must support E and be noexcept");
   }
-public:
-  using properties = property_set<is_receiver<>, is_single<>>;
-
-  single() = default;
-  single(single&& that) noexcept : single() {
-    that.vptr_->op_(that.data_, &data_);
-    std::swap(that.vptr_, vptr_);
-  }
-  PUSHMI_TEMPLATE(class Wrapped)
-    (requires SingleReceiver<wrapped_t<Wrapped>, V, E>
-      PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
-  explicit single(Wrapped obj) : single() {
-    check<Wrapped>();
+  template<class Wrapped>
+  single(Wrapped obj, std::false_type) : single() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -82,10 +71,8 @@ public:
     data_.pobj_ = new Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
-  PUSHMI_TEMPLATE(class Wrapped)
-    (requires SingleReceiver<wrapped_t<Wrapped>, V, E> && insitu<Wrapped>())
-  explicit single(Wrapped obj) noexcept : single() {
-    check<Wrapped>();
+  template<class Wrapped>
+  single(Wrapped obj, std::true_type) noexcept : single() {
     struct s {
       static void op(data& src, data* dst) {
           if (dst)
@@ -112,6 +99,20 @@ public:
     new ((void*)data_.buffer_) Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
+public:
+  using properties = property_set<is_receiver<>, is_single<>>;
+
+  single() = default;
+  single(single&& that) noexcept : single() {
+    that.vptr_->op_(that.data_, &data_);
+    std::swap(that.vptr_, vptr_);
+  }
+  PUSHMI_TEMPLATE(class Wrapped)
+    (requires SingleReceiver<wrapped_t<Wrapped>, V, E>)
+  explicit single(Wrapped obj) noexcept(insitu<Wrapped>())
+    : single{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {
+    check<Wrapped>();
+  }
   ~single() {
     vptr_->op_(data_, nullptr);
   }
@@ -281,7 +282,7 @@ inline auto make_single() -> single<> {
   return {};
 }
 PUSHMI_TEMPLATE(class VF)
-  (requires PUSHMI_BROKEN_SUBSUMPTION(not lazy::Receiver<VF> && not lazy::Invocable<VF&>))
+  (requires PUSHMI_BROKEN_SUBSUMPTION(not defer::Receiver<VF> && not defer::Invocable<VF&>))
 auto make_single(VF vf) -> single<VF, abortEF, ignoreDF> {
   return single<VF, abortEF, ignoreDF>{std::move(vf)};
 }
@@ -290,58 +291,58 @@ auto make_single(on_error_fn<EFN...> ef) -> single<ignoreVF, on_error_fn<EFN...>
   return single<ignoreVF, on_error_fn<EFN...>, ignoreDF>{std::move(ef)};
 }
 PUSHMI_TEMPLATE(class DF)
-  (requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<DF>))
+  (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<DF>))
 auto make_single(DF df) -> single<ignoreVF, abortEF, DF> {
   return single<ignoreVF, abortEF, DF>{std::move(df)};
 }
 PUSHMI_TEMPLATE(class VF, class EF)
-  (requires PUSHMI_BROKEN_SUBSUMPTION(not lazy::Receiver<VF> && not lazy::Invocable<EF&>))
+  (requires PUSHMI_BROKEN_SUBSUMPTION(not defer::Receiver<VF> && not defer::Invocable<EF&>))
 auto make_single(VF vf, EF ef) -> single<VF, EF, ignoreDF> {
   return {std::move(vf), std::move(ef)};
 }
 PUSHMI_TEMPLATE(class EF, class DF)
-  (requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<EF>))
+  (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<EF>))
 auto make_single(EF ef, DF df) -> single<ignoreVF, EF, DF> {
   return {std::move(ef), std::move(df)};
 }
 PUSHMI_TEMPLATE(class VF, class EF, class DF)
-  (requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<VF>))
+  (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<VF>))
 auto make_single(VF vf, EF ef, DF df) -> single<VF, EF, DF> {
   return {std::move(vf), std::move(ef), std::move(df)};
 }
 PUSHMI_TEMPLATE(class Data)
-  (requires lazy::Receiver<Data, is_single<>>)
+  (requires defer::Receiver<Data, is_single<>>)
 auto make_single(Data d) -> single<Data, passDVF, passDEF, passDDF> {
   return single<Data, passDVF, passDEF, passDDF>{std::move(d)};
 }
 PUSHMI_TEMPLATE(class Data, class DVF)
-  (requires lazy::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Invocable<DVF&, Data&>))
+  (requires defer::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Invocable<DVF&, Data&>))
 auto make_single(Data d, DVF vf) -> single<Data, DVF, passDEF, passDDF> {
   return {std::move(d), std::move(vf)};
 }
 PUSHMI_TEMPLATE(class Data, class... DEFN)
-  (requires lazy::Receiver<Data, is_single<>>)
+  (requires defer::Receiver<Data, is_single<>>)
 auto make_single(Data d, on_error_fn<DEFN...> ef) ->
     single<Data, passDVF, on_error_fn<DEFN...>, passDDF> {
   return {std::move(d), std::move(ef)};
 }
 PUSHMI_TEMPLATE(class Data, class DDF)
-  (requires lazy::Receiver<Data, is_single<>> && lazy::Invocable<DDF&, Data&>)
+  (requires defer::Receiver<Data, is_single<>> && defer::Invocable<DDF&, Data&>)
 auto make_single(Data d, DDF df) -> single<Data, passDVF, passDEF, DDF> {
   return {std::move(d), std::move(df)};
 }
 PUSHMI_TEMPLATE(class Data, class DVF, class DEF)
-  (requires lazy::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Invocable<DEF&, Data&>))
+  (requires defer::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Invocable<DEF&, Data&>))
 auto make_single(Data d, DVF vf, DEF ef) -> single<Data, DVF, DEF, passDDF> {
   return {std::move(d), std::move(vf), std::move(ef)};
 }
 PUSHMI_TEMPLATE(class Data, class DEF, class DDF)
-  (requires lazy::Receiver<Data, is_single<>> && lazy::Invocable<DDF&, Data&>)
+  (requires defer::Receiver<Data, is_single<>> && defer::Invocable<DDF&, Data&>)
 auto make_single(Data d, DEF ef, DDF df) -> single<Data, passDVF, DEF, DDF> {
   return {std::move(d), std::move(ef), std::move(df)};
 }
 PUSHMI_TEMPLATE(class Data, class DVF, class DEF, class DDF)
-  (requires lazy::Receiver<Data, is_single<>> && lazy::Invocable<DDF&, Data&>)
+  (requires defer::Receiver<Data, is_single<>> && defer::Invocable<DDF&, Data&>)
 auto make_single(Data d, DVF vf, DEF ef, DDF df) -> single<Data, DVF, DEF, DDF> {
   return {std::move(d), std::move(vf), std::move(ef), std::move(df)};
 }
@@ -352,55 +353,55 @@ auto make_single(Data d, DVF vf, DEF ef, DDF df) -> single<Data, DVF, DEF, DDF>
 single() -> single<>;
 
 PUSHMI_TEMPLATE(class VF)
-  (requires PUSHMI_BROKEN_SUBSUMPTION(not lazy::Receiver<VF> && not lazy::Invocable<VF&>))
+  (requires PUSHMI_BROKEN_SUBSUMPTION(not defer::Receiver<VF> && not defer::Invocable<VF&>))
 single(VF) -> single<VF, abortEF, ignoreDF>;
 
 template <class... EFN>
 single(on_error_fn<EFN...>) -> single<ignoreVF, on_error_fn<EFN...>, ignoreDF>;
 
 PUSHMI_TEMPLATE(class DF)
-  (requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<DF>))
+  (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<DF>))
 single(DF) -> single<ignoreVF, abortEF, DF>;
 
 PUSHMI_TEMPLATE(class VF, class EF)
-  (requires PUSHMI_BROKEN_SUBSUMPTION(not lazy::Receiver<VF> && not lazy::Invocable<EF&>))
+  (requires PUSHMI_BROKEN_SUBSUMPTION(not defer::Receiver<VF> && not defer::Invocable<EF&>))
 single(VF, EF) -> single<VF, EF, ignoreDF>;
 
 PUSHMI_TEMPLATE(class EF, class DF)
-  (requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<EF>))
+  (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<EF>))
 single(EF, DF) -> single<ignoreVF, EF, DF>;
 
 PUSHMI_TEMPLATE(class VF, class EF, class DF)
-  (requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<VF>))
+  (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<VF>))
 single(VF, EF, DF) -> single<VF, EF, DF>;
 
 PUSHMI_TEMPLATE(class Data)
-  (requires lazy::Receiver<Data, is_single<>>)
+  (requires defer::Receiver<Data, is_single<>>)
 single(Data d) -> single<Data, passDVF, passDEF, passDDF>;
 
 PUSHMI_TEMPLATE(class Data, class DVF)
-  (requires lazy::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Invocable<DVF&, Data&>))
+  (requires defer::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Invocable<DVF&, Data&>))
 single(Data d, DVF vf) -> single<Data, DVF, passDEF, passDDF>;
 
 PUSHMI_TEMPLATE(class Data, class... DEFN)
-  (requires lazy::Receiver<Data, is_single<>>)
+  (requires defer::Receiver<Data, is_single<>>)
 single(Data d, on_error_fn<DEFN...>) ->
     single<Data, passDVF, on_error_fn<DEFN...>, passDDF>;
 
 PUSHMI_TEMPLATE(class Data, class DDF)
-  (requires lazy::Receiver<Data, is_single<>> && lazy::Invocable<DDF&, Data&>)
+  (requires defer::Receiver<Data, is_single<>> && defer::Invocable<DDF&, Data&>)
 single(Data d, DDF) -> single<Data, passDVF, passDEF, DDF>;
 
 PUSHMI_TEMPLATE(class Data, class DVF, class DEF)
-  (requires lazy::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Invocable<DEF&, Data&>))
+  (requires defer::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Invocable<DEF&, Data&>))
 single(Data d, DVF vf, DEF ef) -> single<Data, DVF, DEF, passDDF>;
 
 PUSHMI_TEMPLATE(class Data, class DEF, class DDF)
-  (requires lazy::Receiver<Data, is_single<>> && lazy::Invocable<DDF&, Data&>)
+  (requires defer::Receiver<Data, is_single<>> && defer::Invocable<DDF&, Data&>)
 single(Data d, DEF, DDF) -> single<Data, passDVF, DEF, DDF>;
 
 PUSHMI_TEMPLATE(class Data, class DVF, class DEF, class DDF)
-  (requires lazy::Receiver<Data, is_single<>> && lazy::Invocable<DDF&, Data&>)
+  (requires defer::Receiver<Data, is_single<>> && defer::Invocable<DDF&, Data&>)
 single(Data d, DVF vf, DEF ef, DDF df) -> single<Data, DVF, DEF, DDF>;
 #endif
 
diff --git a/folly/experimental/pushmi/include/pushmi/single_deferred.h b/folly/experimental/pushmi/include/pushmi/single_deferred.h
index 076407f03..e350dd56f 100644
--- a/folly/experimental/pushmi/include/pushmi/single_deferred.h
+++ b/folly/experimental/pushmi/include/pushmi/single_deferred.h
@@ -26,22 +26,8 @@ class any_single_deferred {
     void (*submit_)(data&, single<V, E>) = s_submit;
     static constexpr vtable const noop_ {};
   } const* vptr_ = &vtable::noop_;
-  template <class T, class U = std::decay_t<T>>
-  using wrapped_t =
-    std::enable_if_t<!std::is_same<U, any_single_deferred>::value, U>;
- public:
-  using properties = property_set<is_sender<>, is_single<>>;
-
-  any_single_deferred() = default;
-  any_single_deferred(any_single_deferred&& that) noexcept : any_single_deferred() {
-    that.vptr_->op_(that.data_, &data_);
-    std::swap(that.vptr_, vptr_);
-  }
-
-  PUSHMI_TEMPLATE(class Wrapped)
-    (requires SenderTo<wrapped_t<Wrapped>, single<V, E>, is_single<>>
-      PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
-  explicit any_single_deferred(Wrapped obj) : any_single_deferred() {
+  template <class Wrapped>
+  any_single_deferred(Wrapped obj, std::false_type) : any_single_deferred() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -56,10 +42,9 @@ class any_single_deferred {
     data_.pobj_ = new Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
-  PUSHMI_TEMPLATE(class Wrapped)
-    (requires SenderTo<wrapped_t<Wrapped>, single<V, E>, is_single<>>
-      && insitu<Wrapped>())
-  explicit any_single_deferred(Wrapped obj) noexcept : any_single_deferred() {
+  template <class Wrapped>
+  any_single_deferred(Wrapped obj, std::true_type) noexcept
+      : any_single_deferred() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -76,6 +61,23 @@ class any_single_deferred {
     new (data_.buffer_) Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
+  template <class T, class U = std::decay_t<T>>
+  using wrapped_t =
+    std::enable_if_t<!std::is_same<U, any_single_deferred>::value, U>;
+ public:
+  using properties = property_set<is_sender<>, is_single<>>;
+
+  any_single_deferred() = default;
+  any_single_deferred(any_single_deferred&& that) noexcept
+      : any_single_deferred() {
+    that.vptr_->op_(that.data_, &data_);
+    std::swap(that.vptr_, vptr_);
+  }
+
+  PUSHMI_TEMPLATE(class Wrapped)
+    (requires SenderTo<wrapped_t<Wrapped>, single<V, E>, is_single<>>)
+  explicit any_single_deferred(Wrapped obj) noexcept(insitu<Wrapped>())
+    : any_single_deferred{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {}
   ~any_single_deferred() {
     vptr_->op_(data_, nullptr);
   }
@@ -106,7 +108,7 @@ class single_deferred<SF> {
       : sf_(std::move(sf)) {}
 
   PUSHMI_TEMPLATE(class Out)
-    (requires lazy::Receiver<Out, is_single<>> && lazy::Invocable<SF&, Out>)
+    (requires defer::Receiver<Out, is_single<>> && defer::Invocable<SF&, Out>)
   void submit(Out out) {
     sf_(std::move(out));
   }
@@ -127,7 +129,8 @@ class single_deferred_2 {
   constexpr single_deferred_2(Data data, DSF sf)
       : data_(std::move(data)), sf_(std::move(sf)) {}
   PUSHMI_TEMPLATE(class Out)
-    (requires lazy::Receiver<Out, is_single<>> && lazy::Invocable<DSF&, Data&, Out>)
+    (requires defer::Receiver<Out, is_single<>> &&
+        defer::Invocable<DSF&, Data&, Out>)
   void submit(Out out) {
     sf_(data_, std::move(out));
   }
@@ -136,7 +139,7 @@ class single_deferred_2 {
 template <class A, class B>
 using single_deferred_base =
   meta::if_c<
-    Sender<A, is_single<>>,
+    (bool)Sender<A, is_single<>>,
     single_deferred_2<A, B>,
     any_single_deferred<A, B>>;
 } // namespace detail
diff --git a/folly/experimental/pushmi/include/pushmi/time_single_deferred.h b/folly/experimental/pushmi/include/pushmi/time_single_deferred.h
index 67df7cfd2..a6bef4028 100644
--- a/folly/experimental/pushmi/include/pushmi/time_single_deferred.h
+++ b/folly/experimental/pushmi/include/pushmi/time_single_deferred.h
@@ -31,23 +31,9 @@ class any_time_single_deferred {
     void (*submit_)(data&, TP, single<V, E>) = s_submit;
     static constexpr vtable const noop_ = {};
   } const* vptr_ = &vtable::noop_;
-  template <class T, class U = std::decay_t<T>>
-  using wrapped_t =
-    std::enable_if_t<!std::is_same<U, any_time_single_deferred>::value, U>;
-
- public:
-  using properties = property_set<is_time<>, is_single<>>;
-
-  any_time_single_deferred() = default;
-  any_time_single_deferred(any_time_single_deferred&& that) noexcept
-      : any_time_single_deferred() {
-    that.vptr_->op_(that.data_, &data_);
-    std::swap(that.vptr_, vptr_);
-  }
-  PUSHMI_TEMPLATE (class Wrapped)
-    (requires TimeSenderTo<wrapped_t<Wrapped>, single<V, E>>
-      PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
-  explicit any_time_single_deferred(Wrapped obj) : any_time_single_deferred() {
+  template <class Wrapped>
+  any_time_single_deferred(Wrapped obj, std::false_type)
+    : any_time_single_deferred() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -68,10 +54,9 @@ class any_time_single_deferred {
     data_.pobj_ = new Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
-  PUSHMI_TEMPLATE (class Wrapped)
-    (requires TimeSenderTo<wrapped_t<Wrapped>, single<V, E>> &&
-      insitu<Wrapped>())
-  explicit any_time_single_deferred(Wrapped obj) noexcept : any_time_single_deferred() {
+  template <class Wrapped>
+  any_time_single_deferred(Wrapped obj, std::true_type) noexcept
+    : any_time_single_deferred() {
     struct s {
       static void op(data& src, data* dst) {
         if (dst)
@@ -93,6 +78,24 @@ class any_time_single_deferred {
     new (data_.buffer_) Wrapped(std::move(obj));
     vptr_ = &vtbl;
   }
+  template <class T, class U = std::decay_t<T>>
+  using wrapped_t =
+    std::enable_if_t<!std::is_same<U, any_time_single_deferred>::value, U>;
+
+ public:
+  using properties = property_set<is_time<>, is_single<>>;
+
+  any_time_single_deferred() = default;
+  any_time_single_deferred(any_time_single_deferred&& that) noexcept
+      : any_time_single_deferred() {
+    that.vptr_->op_(that.data_, &data_);
+    std::swap(that.vptr_, vptr_);
+  }
+  PUSHMI_TEMPLATE (class Wrapped)
+    (requires TimeSenderTo<wrapped_t<Wrapped>, single<V, E>>)
+  explicit any_time_single_deferred(Wrapped obj) noexcept(insitu<Wrapped>())
+  : any_time_single_deferred{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {
+  }
   ~any_time_single_deferred() {
     vptr_->op_(data_, nullptr);
   }
@@ -173,7 +176,7 @@ class time_single_deferred_2 {
 template <class A, class B, class C>
 using time_single_deferred_base =
   meta::if_c<
-    TimeSender<A, is_single<>>,
+    (bool)TimeSender<A, is_single<>>,
     time_single_deferred_2<A, B, C>,
     any_time_single_deferred<A, B, C>>;
 } // namespace detail
-- 
2.26.2