stdexec: update to latest commit

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: Ie95101c4fce1ec9297053d3c0e3ac265ad4f3960
diff --git a/include/sdbusplus/async/stdexec/__detail/__basic_sender.hpp b/include/sdbusplus/async/stdexec/__detail/__basic_sender.hpp
new file mode 100644
index 0000000..e582f3d
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__basic_sender.hpp
@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 2021-2022 NVIDIA Corporation
+ *
+ * Licensed under the Apache License Version 2.0 with LLVM Exceptions
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *   https://llvm.org/LICENSE.txt
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "../concepts.hpp"
+#include "__execution_fwd.hpp"
+#include "__meta.hpp"
+#include "__type_traits.hpp"
+
+#include <utility> // for tuple_size/tuple_element
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// Generic __sender type
+namespace __detail
+{
+template <class _Sender>
+using __impl_of = decltype((__declval<_Sender>().__impl_));
+
+struct __get_tag
+{
+    template <class _Tag, class... _Rest>
+    _Tag operator()(_Tag, _Rest&&...) const noexcept
+    {
+        return {};
+    }
+};
+
+struct __get_data
+{
+    template <class _Data, class... _Rest>
+    _Data&& operator()(__ignore, _Data&& __data, _Rest&&...) const noexcept
+    {
+        return (_Data&&)__data;
+    }
+};
+
+template <class _Continuation>
+struct __get_children
+{
+    template <class... _Children>
+    auto operator()(__ignore, __ignore, _Children&&...) const noexcept
+        -> __mtype<__minvoke<_Continuation, _Children...>> (*)()
+    {
+        return nullptr;
+    }
+};
+
+STDEXEC_PRAGMA_PUSH()
+STDEXEC_PRAGMA_IGNORE_GNU("-Wunused-local-typedefs")
+
+struct __get_meta
+{
+    template <class _Tag, class _Data, class... _Children>
+    constexpr auto operator()(_Tag, _Data&&, _Children&&...) const noexcept
+    {
+        struct __meta
+        {
+            using __tag = _Tag;
+            using __data = _Data;
+            using __children = __types<_Children...>;
+        };
+
+        return __meta{};
+    }
+};
+
+STDEXEC_PRAGMA_POP()
+
+struct __tie
+{
+    template <class _Tag, class _Data, class... _Children>
+    constexpr auto operator()(_Tag, _Data&& __data,
+                              _Children&&... __children) const noexcept
+    {
+        return std::tuple<_Tag, _Data&&, _Children&&...>{
+            {}, (_Data&&)__data, (_Children&&)__children...};
+    }
+};
+} // namespace __detail
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// __sexpr
+template <class...>
+struct __sexpr
+{
+    using __id = __sexpr;
+    using __t = __sexpr;
+};
+
+template <class _ImplFn>
+struct __sexpr<_ImplFn>
+{
+    using is_sender = void;
+    using __t = __sexpr;
+    using __id = __sexpr;
+    using __meta_t = __call_result_t<_ImplFn, __cp, __detail::__get_meta>;
+    using __tag_t = typename __meta_t::__tag;
+    using __data_t = typename __meta_t::__data;
+    using __children_t = typename __meta_t::__children;
+    using __arity_t = __mapply<__msize, __children_t>;
+
+    STDEXEC_ATTRIBUTE((always_inline)) //
+    static __tag_t __tag() noexcept
+    {
+        return {};
+    }
+
+    mutable _ImplFn __impl_;
+
+    STDEXEC_ATTRIBUTE((host, device, always_inline))
+    explicit __sexpr(_ImplFn __impl) : __impl_((_ImplFn&&)__impl) {}
+
+    template <same_as<get_env_t> _Tag, same_as<__sexpr> _Self>
+    STDEXEC_ATTRIBUTE((always_inline))                         //
+    friend auto tag_invoke(_Tag, const _Self& __self) noexcept //
+        -> __msecond<__if_c<same_as<_Tag, get_env_t>>,         //
+                     decltype(__self.__tag().get_env(__self))>
+    {
+        static_assert(noexcept(__self.__tag().get_env(__self)));
+        return __tag_t::get_env(__self);
+    }
+
+    template <same_as<get_completion_signatures_t> _Tag,
+              __decays_to<__sexpr> _Self, class _Env>
+    STDEXEC_ATTRIBUTE((always_inline))                         //
+    friend auto tag_invoke(_Tag, _Self&& __self, _Env&& __env) //
+        -> __msecond<__if_c<same_as<_Tag, get_completion_signatures_t>>,
+                     decltype(__self.__tag().get_completion_signatures(
+                         (_Self&&)__self, (_Env&&)__env))>
+    {
+        return {};
+    }
+
+    // BUGBUG fix receiver constraint here:
+    template <same_as<connect_t> _Tag, __decays_to<__sexpr> _Self,
+              /*receiver*/ class _Receiver>
+    STDEXEC_ATTRIBUTE((always_inline))                                  //
+    friend auto tag_invoke(_Tag, _Self&& __self, _Receiver&& __rcvr)    //
+        noexcept(noexcept(__self.__tag().connect((_Self&&)__self,
+                                                 (_Receiver&&)__rcvr))) //
+        -> __msecond<__if_c<same_as<_Tag, connect_t>>,
+                     decltype(__self.__tag().connect((_Self&&)__self,
+                                                     (_Receiver&&)__rcvr))>
+    {
+        return __tag_t::connect((_Self&&)__self, (_Receiver&&)__rcvr);
+    }
+
+    template <class _Sender, class _ApplyFn>
+    STDEXEC_ATTRIBUTE((always_inline))                                   //
+    STDEXEC_DEFINE_EXPLICIT_THIS_MEMFN(auto apply)(this _Sender&& __sndr,
+                                                   _ApplyFn&& __fun)     //
+        noexcept(__nothrow_callable<__detail::__impl_of<_Sender>,
+                                    __copy_cvref_fn<_Sender>, _ApplyFn>) //
+        -> __call_result_t<__detail::__impl_of<_Sender>,
+                           __copy_cvref_fn<_Sender>, _ApplyFn>
+    {                                                                //
+        return ((_Sender&&)__sndr)
+            .__impl_(__copy_cvref_fn<_Sender>(), (_ApplyFn&&)__fun); //
+    }
+
+    template <std::size_t _Idx, __decays_to_derived_from<__sexpr> _Self>
+    STDEXEC_ATTRIBUTE((always_inline))
+    friend decltype(auto) get(_Self&& __self) noexcept
+        requires(_Idx < (__v<__arity_t> + 2))
+    {
+        if constexpr (_Idx == 0)
+        {
+            return __tag_t();
+        }
+        else
+        {
+            return __self.__impl_(__copy_cvref_fn<_Self>(),
+                                  __nth_pack_element<_Idx>);
+        }
+        STDEXEC_UNREACHABLE();
+    }
+};
+
+template <class _ImplFn>
+STDEXEC_ATTRIBUTE((host, device))
+__sexpr(_ImplFn) -> __sexpr<_ImplFn>;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// __make_sexpr
+namespace __detail
+{
+template <class _Tag>
+struct __make_sexpr_t
+{
+    template <class _Data = __, class... _Children>
+    constexpr auto operator()(_Data __data = {}, _Children... __children) const;
+};
+
+#if STDEXEC_NVHPC() || (STDEXEC_GCC() && __GNUC__ < 13)
+// The NVIDIA HPC compiler and gcc prior to v13 struggle with capture
+// initializers for a parameter pack. As a workaround, we use a wrapper that
+// performs moves when non-const lvalues are copied. That constructor is
+// only used when capturing the variables, never when the resulting lambda
+// is copied or moved.
+
+// Move-by-copy
+template <class _Ty>
+struct __mbc
+{
+    template <class _Cvref>
+    using __f = __minvoke<_Cvref, _Ty>;
+
+    _Ty __value;
+
+    STDEXEC_ATTRIBUTE((always_inline))
+    explicit __mbc(_Ty& __v) noexcept(
+        std::is_nothrow_move_constructible_v<_Ty>) :
+        __value((_Ty&&)__v)
+    {}
+
+    // This is a template so as to not be considered a copy/move constructor.
+    // Therefore, it doesn't suppress the generation of the default copy/move
+    // constructors.
+    STDEXEC_ATTRIBUTE((always_inline))
+    __mbc(same_as<__mbc> auto& __that) noexcept(
+        std::is_nothrow_move_constructible_v<_Ty>) :
+        __value(static_cast<_Ty&&>(__that.__value))
+    {}
+};
+
+// Rather strange definition of the lambda return type below is to reap the
+// benefits of SFINAE without nvc++ encoding the whole return type into the
+// symbol name.
+template <class _Ty>
+extern _Ty (*__f)();
+
+// Anonymous namespace here is to avoid symbol name collisions with the
+// lambda functions returned by __make_tuple.
+namespace
+{
+constexpr auto __make_tuple = //
+    []<class _Tag, class... _Captures>(_Tag, _Captures&&... __captures) {
+    return
+        [=]<class _Cvref, class _Fun>(_Cvref __cvref, _Fun&& __fun) mutable  //
+        noexcept(
+            __nothrow_callable<_Fun, _Tag, __minvoke<_Captures, _Cvref>...>) //
+        -> decltype(__f<__call_result_t<_Fun, _Tag,
+                                        __minvoke<_Captures, _Cvref>...>>())
+            requires __callable<_Fun, _Tag, __minvoke<_Captures, _Cvref>...>
+    {
+        return ((_Fun&&)__fun)(
+            _Tag(),
+            const_cast<__minvoke<_Captures, _Cvref>&&>(__captures.__value)...);
+    };
+};
+} // anonymous namespace
+
+template <class _Tag>
+template <class _Data, class... _Children>
+constexpr auto __make_sexpr_t<_Tag>::operator()(_Data __data,
+                                                _Children... __children) const
+{
+    return __sexpr{__make_tuple(_Tag(), __detail::__mbc(__data),
+                                __detail::__mbc(__children)...)};
+}
+#else
+// Anonymous namespace here is to avoid symbol name collisions with the
+// lambda functions returned by __make_tuple.
+namespace
+{
+constexpr auto __make_tuple = //
+    []<class _Tag, class... _Captures>(_Tag, _Captures&&... __captures) {
+    return
+        [... __captures = (_Captures&&)__captures]<class _Cvref, class _Fun>(
+            _Cvref, _Fun&& __fun) mutable                                    //
+        noexcept(
+            __nothrow_callable<_Fun, _Tag, __minvoke<_Cvref, _Captures>...>) //
+        -> __call_result_t<_Fun, _Tag, __minvoke<_Cvref, _Captures>...>
+            requires __callable<_Fun, _Tag, __minvoke<_Cvref, _Captures>...>
+    {
+        return ((_Fun&&)__fun)(
+            _Tag(), const_cast<__minvoke<_Cvref, _Captures>&&>(__captures)...);
+    };
+};
+} // anonymous namespace
+
+template <class _Tag>
+template <class _Data, class... _Children>
+constexpr auto __make_sexpr_t<_Tag>::operator()(_Data __data,
+                                                _Children... __children) const
+{
+    return __sexpr{
+        __make_tuple(_Tag(), (_Data&&)__data, (_Children&&)__children...)};
+};
+#endif
+
+template <class _Tag>
+inline constexpr __make_sexpr_t<_Tag> __make_sexpr{};
+} // namespace __detail
+
+using __detail::__make_sexpr;
+
+template <class _Tag, class _Data, class... _Children>
+using __sexpr_t = __result_of<__make_sexpr<_Tag>, _Data, _Children...>;
+
+namespace __detail
+{
+struct __sexpr_apply_t
+{
+    template <class _Sender, class _ApplyFn>
+    STDEXEC_ATTRIBUTE((always_inline))                        //
+    auto operator()(_Sender&& __sndr, _ApplyFn&& __fun) const //
+        noexcept(noexcept(STDEXEC_CALL_EXPLICIT_THIS_MEMFN(
+            ((_Sender&&)__sndr), apply)((_ApplyFn&&)__fun)))  //
+        -> decltype(STDEXEC_CALL_EXPLICIT_THIS_MEMFN(((_Sender&&)__sndr),
+                                                     apply)((_ApplyFn&&)__fun))
+    {
+        return STDEXEC_CALL_EXPLICIT_THIS_MEMFN(((_Sender&&)__sndr),
+                                                apply)((_ApplyFn&&)__fun); //
+    }
+};
+} // namespace __detail
+
+using __detail::__sexpr_apply_t;
+inline constexpr __sexpr_apply_t __sexpr_apply{};
+
+template <class _Sender, class _ApplyFn>
+using __sexpr_apply_result_t =
+    __call_result_t<__sexpr_apply_t, _Sender, _ApplyFn>;
+
+namespace __detail
+{
+template <class _Sender>
+using __meta_of =
+    __call_result_t<__sexpr_apply_t, _Sender, __detail::__get_meta>;
+}
+
+template <class _Sender>
+using __tag_of = typename __detail::__meta_of<_Sender>::__tag;
+
+template <class _Sender>
+using __data_of = typename __detail::__meta_of<_Sender>::__data;
+
+template <class _Sender, class _Continuation = __q<__types>>
+using __children_of = //
+    __mapply<_Continuation, typename __detail::__meta_of<_Sender>::__children>;
+
+template <class _Ny, class _Sender>
+using __nth_child_of = __children_of<_Sender, __mbind_front_q<__m_at, _Ny>>;
+
+template <std::size_t _Ny, class _Sender>
+using __nth_child_of_c =
+    __children_of<_Sender, __mbind_front_q<__m_at, __msize_t<_Ny>>>;
+
+template <class _Sender>
+using __child_of = __children_of<_Sender, __q<__mfront>>;
+
+template <class _Sender>
+inline constexpr std::size_t __nbr_children_of =
+    __v<__children_of<_Sender, __msize>>;
+
+template <class _Sender>
+concept sender_expr = //
+    __mvalid<__tag_of, _Sender>;
+
+template <class _Sender, class _Tag>
+concept sender_expr_for = //
+    sender_expr<_Sender> && same_as<__tag_of<_Sender>, _Tag>;
+
+// The __name_of utility defined below is used to pretty-print the type names of
+// senders in compiler diagnostics.
+namespace __detail
+{
+template <class _Sender>
+extern __q<__midentity> __name_of_v;
+
+template <class _Sender>
+using __name_of_fn = decltype(__name_of_v<_Sender>);
+
+template <class _Sender>
+using __name_of = __minvoke<__name_of_fn<_Sender>, _Sender>;
+
+struct __basic_sender_name
+{
+    template <class _Sender>
+    using __f = //
+        __call_result_t<__sexpr_apply_result_t<_Sender, __basic_sender_name>>;
+
+    template <class _Tag, class _Data, class... _Children>
+    auto operator()(_Tag, _Data&&, _Children&&...) const //
+        -> __sexpr<_Tag, _Data, __name_of<_Children>...> (*)();
+};
+
+struct __id_name
+{
+    template <class _Sender>
+    using __f = __name_of<__id<_Sender>>;
+};
+
+template <class _Sender>
+extern __mcompose<__cplr, __name_of_fn<_Sender>> __name_of_v<_Sender&>;
+
+template <class _Sender>
+extern __mcompose<__cprr, __name_of_fn<_Sender>> __name_of_v<_Sender&&>;
+
+template <class _Sender>
+extern __mcompose<__cpclr, __name_of_fn<_Sender>> __name_of_v<const _Sender&>;
+
+template <class _Impl>
+extern __basic_sender_name __name_of_v<__sexpr<_Impl>>;
+
+template <__has_id _Sender>
+    requires(!same_as<__id<_Sender>, _Sender>)
+extern __id_name __name_of_v<_Sender>;
+
+template <class _Ty>
+_Ty __remove_rvalue_reference_fn(_Ty&&);
+
+template <class _Ty>
+using __remove_rvalue_reference_t =
+    decltype(__detail::__remove_rvalue_reference_fn(__declval<_Ty>()));
+} // namespace __detail
+
+template <class _Sender>
+using __name_of = __detail::__name_of<_Sender>;
+} // namespace stdexec
+
+namespace std
+{
+template <class _Impl>
+struct tuple_size<stdexec::__sexpr<_Impl>> :
+    integral_constant<
+        size_t, stdexec::__v<typename stdexec::__sexpr<_Impl>::__arity_t> + 2>
+{};
+
+template <size_t _Idx, class _Impl>
+struct tuple_element<_Idx, stdexec::__sexpr<_Impl>>
+{
+    using type =
+        stdexec::__detail::__remove_rvalue_reference_t<stdexec::__call_result_t<
+            _Impl, stdexec::__cp, stdexec::__nth_pack_element_t<_Idx>>>;
+};
+} // namespace std
diff --git a/include/sdbusplus/async/stdexec/__detail/__config.hpp b/include/sdbusplus/async/stdexec/__detail/__config.hpp
index 8772163..7cfd3dc 100644
--- a/include/sdbusplus/async/stdexec/__detail/__config.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__config.hpp
@@ -19,13 +19,23 @@
 #error This library requires the use of C++20.
 #endif
 
+#if __has_include(<version>)
+#include <version>
+#else
+#include <ciso646> // For stdlib feature-test macros when <version> is not available
+#endif
+
 #include <cassert>
+#include <version>
+
+#define STDEXEC_STRINGIZE(_ARG) #_ARG
 
 #define STDEXEC_CAT_(_XP, ...) _XP##__VA_ARGS__
 #define STDEXEC_CAT(_XP, ...) STDEXEC_CAT_(_XP, __VA_ARGS__)
 
 #define STDEXEC_EXPAND(...) __VA_ARGS__
 #define STDEXEC_EVAL(_MACRO, ...) _MACRO(__VA_ARGS__)
+#define STDEXEC_EAT(...)
 
 #define STDEXEC_NOT(_XP) STDEXEC_CAT(STDEXEC_NOT_, _XP)
 #define STDEXEC_NOT_0 1
@@ -40,46 +50,184 @@
     STDEXEC_EXPAND(STDEXEC_COUNT_(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1))
 #define STDEXEC_COUNT_(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _NP, ...) _NP
 
-#define STDEXEC_CHECK(...) STDEXEC_EXPAND(STDEXEC_CHECK_N(__VA_ARGS__, 0, ))
-#define STDEXEC_CHECK_N(_XP, _NP, ...) _NP
-#define STDEXEC_PROBE(_XP) _XP, 1,
+#define STDEXEC_CHECK(...) STDEXEC_EXPAND(STDEXEC_CHECK_(__VA_ARGS__, 0, ))
+#define STDEXEC_CHECK_(_XP, _NP, ...) _NP
+#define STDEXEC_PROBE(...) STDEXEC_PROBE_(__VA_ARGS__, 1)
+#define STDEXEC_PROBE_(_XP, _NP, ...) _XP, _NP,
 
-#if defined(__NVCOMPILER)
-#define STDEXEC_NVHPC() 1
+////////////////////////////////////////////////////////////////////////////////
+// STDEXEC_FOR_EACH
+//   Inspired by "Recursive macros with C++20 __VA_OPT__", by David Mazières
+//   https://www.scs.stanford.edu/~dm/blog/va-opt.html
+#define STDEXEC_EXPAND_R(...)                                                  \
+    STDEXEC_EXPAND_R1(                                                         \
+        STDEXEC_EXPAND_R1(STDEXEC_EXPAND_R1(STDEXEC_EXPAND_R1(__VA_ARGS__))))  \
+    /**/
+#define STDEXEC_EXPAND_R1(...)                                                 \
+    STDEXEC_EXPAND_R2(                                                         \
+        STDEXEC_EXPAND_R2(STDEXEC_EXPAND_R2(STDEXEC_EXPAND_R2(__VA_ARGS__))))  \
+    /**/
+#define STDEXEC_EXPAND_R2(...)                                                 \
+    STDEXEC_EXPAND_R3(                                                         \
+        STDEXEC_EXPAND_R3(STDEXEC_EXPAND_R3(STDEXEC_EXPAND_R3(__VA_ARGS__))))  \
+    /**/
+#define STDEXEC_EXPAND_R3(...)                                                 \
+    STDEXEC_EXPAND(                                                            \
+        STDEXEC_EXPAND(STDEXEC_EXPAND(STDEXEC_EXPAND(__VA_ARGS__))))           \
+    /**/
+
+#define STDEXEC_PARENS ()
+#define STDEXEC_FOR_EACH(_MACRO, ...)                                          \
+    __VA_OPT__(STDEXEC_EXPAND_R(STDEXEC_FOR_EACH_HELPER(_MACRO, __VA_ARGS__))) \
+    /**/
+#define STDEXEC_FOR_EACH_HELPER(_MACRO, _A1, ...)                              \
+    _MACRO(_A1)                                                                \
+    __VA_OPT__(STDEXEC_FOR_EACH_AGAIN STDEXEC_PARENS(_MACRO, __VA_ARGS__)) /**/
+#define STDEXEC_FOR_EACH_AGAIN() STDEXEC_FOR_EACH_HELPER
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// If tail is non-empty, expand to the tail. Otherwise, expand to the head
+#define STDEXEC_HEAD_OR_TAIL(_XP, ...)                                         \
+    STDEXEC_EXPAND __VA_OPT__((__VA_ARGS__)STDEXEC_EAT)(_XP)
+
+// If tail is non-empty, expand to nothing. Otherwise, expand to the head
+#define STDEXEC_HEAD_OR_NULL(_XP, ...)                                         \
+    STDEXEC_EXPAND __VA_OPT__(() STDEXEC_EAT)(_XP)
+
+// When used with no arguments, these macros expand to 1 if the current
+// compiler corresponds to the macro name; 0, otherwise. When used with
+// arguments, they expand to the arguments if if the current compiler
+// corresponds to the macro name; nothing, otherwise.
+#if defined(__NVCC__)
+#define STDEXEC_NVCC(...) STDEXEC_HEAD_OR_TAIL(1, __VA_ARGS__)
+#elif defined(__NVCOMPILER)
+#define STDEXEC_NVHPC(...) STDEXEC_HEAD_OR_TAIL(1, __VA_ARGS__)
+#elif defined(__EDG__)
+#define STDEXEC_EDG(...) STDEXEC_HEAD_OR_TAIL(1, __VA_ARGS__)
 #elif defined(__clang__)
-#define STDEXEC_CLANG() 1
+#define STDEXEC_CLANG(...) STDEXEC_HEAD_OR_TAIL(1, __VA_ARGS__)
+#if defined(_MSC_VER)
+#define STDEXEC_CLANG_CL(...) STDEXEC_HEAD_OR_TAIL(1, __VA_ARGS__)
+#endif
 #elif defined(__GNUC__)
-#define STDEXEC_GCC() 1
+#define STDEXEC_GCC(...) STDEXEC_HEAD_OR_TAIL(1, __VA_ARGS__)
 #elif defined(_MSC_VER)
-#define STDEXEC_MSVC() 1
+#define STDEXEC_MSVC(...) STDEXEC_HEAD_OR_TAIL(1, __VA_ARGS__)
 #endif
 
+#ifndef STDEXEC_NVCC
+#define STDEXEC_NVCC(...) STDEXEC_HEAD_OR_NULL(0, __VA_ARGS__)
+#endif
 #ifndef STDEXEC_NVHPC
-#define STDEXEC_NVHPC() 0
+#define STDEXEC_NVHPC(...) STDEXEC_HEAD_OR_NULL(0, __VA_ARGS__)
+#endif
+#ifndef STDEXEC_EDG
+#define STDEXEC_EDG(...) STDEXEC_HEAD_OR_NULL(0, __VA_ARGS__)
 #endif
 #ifndef STDEXEC_CLANG
-#define STDEXEC_CLANG() 0
+#define STDEXEC_CLANG(...) STDEXEC_HEAD_OR_NULL(0, __VA_ARGS__)
+#endif
+#ifndef STDEXEC_CLANG_CL
+#define STDEXEC_CLANG_CL(...) STDEXEC_HEAD_OR_NULL(0, __VA_ARGS__)
 #endif
 #ifndef STDEXEC_GCC
-#define STDEXEC_GCC() 0
+#define STDEXEC_GCC(...) STDEXEC_HEAD_OR_NULL(0, __VA_ARGS__)
 #endif
 #ifndef STDEXEC_MSVC
-#define STDEXEC_MSVC() 0
+#define STDEXEC_MSVC(...) STDEXEC_HEAD_OR_NULL(0, __VA_ARGS__)
 #endif
 
-#if STDEXEC_CLANG()
-#define STDEXEC_STRINGIZE(_ARG) #_ARG
+////////////////////////////////////////////////////////////////////////////////////////////////////
+#ifdef __CUDACC__
+#define STDEXEC_CUDA(...) STDEXEC_HEAD_OR_TAIL(1, __VA_ARGS__)
+#else
+#define STDEXEC_CUDA(...) STDEXEC_HEAD_OR_NULL(0, __VA_ARGS__)
+#endif
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// For portably declaring attributes on functions and types
+//   Usage:
+//
+//   STDEXEC_ATTRIBUTE((attr1, attr2, ...))
+//   void foo() { ... }
+#define STDEXEC_ATTRIBUTE(_XP)                                                 \
+    STDEXEC_FOR_EACH(STDEXEC_ATTR, STDEXEC_EXPAND _XP)
+#define STDEXEC_ATTR(_ATTR)                                                    \
+    STDEXEC_CAT(STDEXEC_ATTR_WHICH_,                                           \
+                STDEXEC_CHECK(STDEXEC_CAT(STDEXEC_ATTR_, _ATTR)))              \
+    (_ATTR)
+
+// unknown attributes are treated like C++-style attributes
+#define STDEXEC_ATTR_WHICH_0(_ATTR) [[_ATTR]]
+
+// custom handling for specific attribute types
+#define STDEXEC_ATTR_WHICH_1(_ATTR) STDEXEC_CUDA(__host__)
+#define STDEXEC_ATTR_host STDEXEC_PROBE(~, 1)
+#define STDEXEC_ATTR___host__ STDEXEC_PROBE(~, 1)
+
+#define STDEXEC_ATTR_WHICH_2(_ATTR) STDEXEC_CUDA(__device__)
+#define STDEXEC_ATTR_device STDEXEC_PROBE(~, 2)
+#define STDEXEC_ATTR___device__ STDEXEC_PROBE(~, 2)
+
+#if STDEXEC_NVHPC()
+// NVBUG #4067067: NVHPC does not fully support [[no_unique_address]]
+#define STDEXEC_ATTR_WHICH_3(_ATTR) /*nothing*/
+#elif STDEXEC_MSVC()
+// MSVCBUG
+// https://developercommunity.visualstudio.com/t/Incorrect-codegen-when-using-msvc::no_/10452874
+#define STDEXEC_ATTR_WHICH_3(_ATTR) // [[msvc::no_unique_address]]
+#elif STDEXEC_CLANG_CL()
+// clang-cl does not support: https://reviews.llvm.org/D110485
+#define STDEXEC_ATTR_WHICH_3(_ATTR) // [[msvc::no_unique_address]]
+#else
+#define STDEXEC_ATTR_WHICH_3(_ATTR) [[no_unique_address]]
+#endif
+#define STDEXEC_ATTR_no_unique_address STDEXEC_PROBE(~, 3)
+
+#if STDEXEC_MSVC()
+#define STDEXEC_ATTR_WHICH_4(_ATTR) __forceinline
+#elif STDEXEC_CLANG()
+#define STDEXEC_ATTR_WHICH_4(_ATTR)                                            \
+    __attribute__((__always_inline__, __artificial__, __nodebug__)) inline
+#elif defined(__GNUC__)
+#define STDEXEC_ATTR_WHICH_4(_ATTR)                                            \
+    __attribute__((__always_inline__, __artificial__)) inline
+#else
+#define STDEXEC_ATTR_WHICH_4(_ATTR) /*nothing*/
+#endif
+#define STDEXEC_ATTR_always_inline STDEXEC_PROBE(~, 4)
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// warning push/pop portability macros
+#if STDEXEC_NVCC()
+#define STDEXEC_PRAGMA_PUSH() _Pragma("nv_diagnostic push")
+#define STDEXEC_PRAGMA_POP() _Pragma("nv_diagnostic pop")
+#define STDEXEC_PRAGMA_IGNORE_EDG(...)                                         \
+    _Pragma(STDEXEC_STRINGIZE(nv_diag_suppress __VA_ARGS__))
+#elif STDEXEC_NVHPC() || STDEXEC_EDG()
+#define STDEXEC_PRAGMA_PUSH()                                                  \
+    _Pragma("diagnostic push") STDEXEC_PRAGMA_IGNORE_EDG(invalid_error_number)
+#define STDEXEC_PRAGMA_POP() _Pragma("diagnostic pop")
+#define STDEXEC_PRAGMA_IGNORE_EDG(...)                                         \
+    _Pragma(STDEXEC_STRINGIZE(diag_suppress __VA_ARGS__))
+#elif STDEXEC_CLANG() || STDEXEC_GCC()
 #define STDEXEC_PRAGMA_PUSH() _Pragma("GCC diagnostic push")
 #define STDEXEC_PRAGMA_POP() _Pragma("GCC diagnostic pop")
-#define STDEXEC_PRAGMA_IGNORE(_ARG)                                            \
-    _Pragma(STDEXEC_STRINGIZE(GCC diagnostic ignored _ARG))
+#define STDEXEC_PRAGMA_IGNORE_GNU(...)                                         \
+    _Pragma(STDEXEC_STRINGIZE(GCC diagnostic ignored __VA_ARGS__))
 #else
 #define STDEXEC_PRAGMA_PUSH()
 #define STDEXEC_PRAGMA_POP()
-#define STDEXEC_PRAGMA_IGNORE(_ARG)
 #endif
 
-#ifdef __has_builtin
+#ifndef STDEXEC_PRAGMA_IGNORE_GNU
+#define STDEXEC_PRAGMA_IGNORE_GNU(...)
+#endif
+#ifndef STDEXEC_PRAGMA_IGNORE_EDG
+#define STDEXEC_PRAGMA_IGNORE_EDG(...)
+#endif
+
+#if !STDEXEC_MSVC() && defined(__has_builtin)
 #define STDEXEC_HAS_BUILTIN __has_builtin
 #else
 #define STDEXEC_HAS_BUILTIN(...) 0
@@ -92,7 +240,7 @@
     std::is_trivially_copyable_v<__VA_ARGS__>
 #endif
 
-#if STDEXEC_HAS_BUILTIN(__is_base_of) || STDEXEC_MSVC()
+#if STDEXEC_HAS_BUILTIN(__is_base_of) || (_MSC_VER >= 1914)
 #define STDEXEC_IS_BASE_OF(...) __is_base_of(__VA_ARGS__)
 #else
 #define STDEXEC_IS_BASE_OF(...) std::is_base_of_v<__VA_ARGS__>
@@ -106,6 +254,22 @@
 #define STDEXEC_IS_CONVERTIBLE_TO(...) std::is_convertible_v<__VA_ARGS__>
 #endif
 
+#if STDEXEC_HAS_BUILTIN(__is_const)
+#define STDEXEC_IS_CONST(...) __is_const(__VA_ARGS__)
+#else
+#define STDEXEC_IS_CONST(...) stdexec::__is_const<__VA_ARGS__>
+#endif
+
+#if defined(__cpp_lib_unreachable) && __cpp_lib_unreachable >= 202202L
+#define STDEXEC_UNREACHABLE() std::unreachable()
+#elif STDEXEC_HAS_BUILTIN(__builtin_unreachable)
+#define STDEXEC_UNREACHABLE() __builtin_unreachable()
+#elif STDEXEC_MSVC()
+#define STDEXEC_UNREACHABLE(...) __assume(false)
+#else
+#define STDEXEC_UNREACHABLE(...) std::terminate()
+#endif
+
 // Before gcc-12, gcc really didn't like tuples or variants of immovable types
 #if STDEXEC_GCC() && (__GNUC__ < 12)
 #define STDEXEC_IMMOVABLE(_XP) _XP(_XP&&)
@@ -113,33 +277,21 @@
 #define STDEXEC_IMMOVABLE(_XP) _XP(_XP&&) = delete
 #endif
 
-// NVBUG #4067067
-#if STDEXEC_NVHPC()
-#define STDEXEC_NO_UNIQUE_ADDRESS
-#else
-#define STDEXEC_NO_UNIQUE_ADDRESS [[no_unique_address]]
-#endif
-
 // BUG (gcc PR93711): copy elision fails when initializing a
 // [[no_unique_address]] field from a function returning an object
 // of class type by value
 #if STDEXEC_GCC()
 #define STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS
 #else
-#define STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS [[no_unique_address]]
-#endif
-
-#if STDEXEC_CLANG() && defined(__CUDACC__)
-#define STDEXEC_DETAIL_CUDACC_HOST_DEVICE __host__ __device__
-#else
-#define STDEXEC_DETAIL_CUDACC_HOST_DEVICE
+#define STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS                                    \
+    STDEXEC_ATTRIBUTE((no_unique_address))
 #endif
 
 #if STDEXEC_NVHPC()
 #include <nv/target>
 #define STDEXEC_TERMINATE()                                                    \
     NV_IF_TARGET(NV_IS_HOST, (std::terminate();), (__trap();)) void()
-#elif STDEXEC_CLANG() && defined(__CUDACC__) && defined(__CUDA_ARCH__)
+#elif STDEXEC_CLANG() && STDEXEC_CUDA() && defined(__CUDA_ARCH__)
 #define STDEXEC_TERMINATE()                                                    \
     __trap();                                                                  \
     __builtin_unreachable()
@@ -147,6 +299,22 @@
 #define STDEXEC_TERMINATE() std::terminate()
 #endif
 
+// Before clang-16, clang did not like libstdc++'s ranges implementation
+#if __has_include(<ranges>) && \
+  (defined(__cpp_lib_ranges) && __cpp_lib_ranges >= 201911L) && \
+  (!STDEXEC_CLANG() || __clang_major__ >= 16 || defined(_LIBCPP_VERSION))
+#define STDEXEC_HAS_STD_RANGES() 1
+#else
+#define STDEXEC_HAS_STD_RANGES() 0
+#endif
+
+#if __has_include(<memory_resource>) && \
+  (defined(__cpp_lib_memory_resource) && __cpp_lib_memory_resource >= 201603L)
+#define STDEXEC_HAS_STD_MEMORY_RESOURCE() 1
+#else
+#define STDEXEC_HAS_STD_MEMORY_RESOURCE() 0
+#endif
+
 #ifdef STDEXEC_ASSERT
 #error                                                                         \
     "Redefinition of STDEXEC_ASSERT is not permitted. Define STDEXEC_ASSERT_FN instead."
@@ -163,5 +331,68 @@
 #define STDEXEC_ASSERT_FN assert
 #endif
 
+#define STDEXEC_AUTO_RETURN(...)                                               \
+    noexcept(noexcept(__VA_ARGS__))->decltype(__VA_ARGS__)                     \
+    {                                                                          \
+        return __VA_ARGS__;                                                    \
+    }
+
+// GCC 13 implements lexical friendship, but it is incomplete. See
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111018
+#if STDEXEC_CLANG() // || (STDEXEC_GCC() && __GNUC__ >= 13)
+#define STDEXEC_FRIENDSHIP_IS_LEXICAL() 1
+#else
+#define STDEXEC_FRIENDSHIP_IS_LEXICAL() 0
+#endif
+
+#if defined(__cpp_explicit_this_parameter) &&                                  \
+    (__cpp_explicit_this_parameter >= 202110)
+#define STDEXEC_EXPLICIT_THIS(...) STDEXEC_HEAD_OR_TAIL(1, __VA_ARGS__)
+#else
+#define STDEXEC_EXPLICIT_THIS(...) STDEXEC_HEAD_OR_NULL(0, __VA_ARGS__)
+#endif
+
+#if STDEXEC_EXPLICIT_THIS()
+#define STDEXEC_DEFINE_EXPLICIT_THIS_MEMFN(...) __VA_ARGS__
+#define STDEXEC_CALL_EXPLICIT_THIS_MEMFN(_OBJ, _NAME) (_OBJ)._NAME( STDEXEC_CALL_EXPLICIT_THIS_MEMFN_DETAIL
+#define STDEXEC_CALL_EXPLICIT_THIS_MEMFN_DETAIL(...) __VA_ARGS__ )
+#else
+#define STDEXEC_DEFINE_EXPLICIT_THIS_MEMFN(...) static __VA_ARGS__(STDEXEC_FUN_ARGS
+#define STDEXEC_CALL_EXPLICIT_THIS_MEMFN(_OBJ, _NAME) (_OBJ)._NAME((_OBJ) STDEXEC_CALL_EXPLICIT_THIS_MEMFN_DETAIL
+#define STDEXEC_CALL_EXPLICIT_THIS_MEMFN_DETAIL(...) __VA_OPT__(, ) __VA_ARGS__)
+#define STDEXEC_EAT_THIS_DETAIL_this
+#define STDEXEC_FUN_ARGS(...) STDEXEC_CAT(STDEXEC_EAT_THIS_DETAIL_, __VA_ARGS__))
+#endif
+
+// Configure extra type checking
+#define STDEXEC_TYPE_CHECKING_ZERO() 0
+#define STDEXEC_TYPE_CHECKING_ONE() 1
+#define STDEXEC_TYPE_CHECKING_TWO() 2
+
+#define STDEXEC_PROBE_TYPE_CHECKING_ STDEXEC_TYPE_CHECKING_ONE
+#define STDEXEC_PROBE_TYPE_CHECKING_0 STDEXEC_TYPE_CHECKING_ZERO
+#define STDEXEC_PROBE_TYPE_CHECKING_1 STDEXEC_TYPE_CHECKING_ONE
+#define STDEXEC_PROBE_TYPE_CHECKING_STDEXEC_ENABLE_EXTRA_TYPE_CHECKING         \
+    STDEXEC_TYPE_CHECKING_TWO
+
+#define STDEXEC_TYPE_CHECKING_WHICH3(...)                                      \
+    STDEXEC_PROBE_TYPE_CHECKING_##__VA_ARGS__
+#define STDEXEC_TYPE_CHECKING_WHICH2(...)                                      \
+    STDEXEC_TYPE_CHECKING_WHICH3(__VA_ARGS__)
+#define STDEXEC_TYPE_CHECKING_WHICH                                            \
+    STDEXEC_TYPE_CHECKING_WHICH2(STDEXEC_ENABLE_EXTRA_TYPE_CHECKING)
+
+#ifndef STDEXEC_ENABLE_EXTRA_TYPE_CHECKING
+#define STDEXEC_ENABLE_EXTRA_TYPE_CHECKING() 0
+#elif STDEXEC_TYPE_CHECKING_WHICH() == 2
+// do nothing
+#elif STDEXEC_TYPE_CHECKING_WHICH() == 0
+#undef STDEXEC_ENABLE_EXTRA_TYPE_CHECKING
+#define STDEXEC_ENABLE_EXTRA_TYPE_CHECKING() 0
+#else
+#undef STDEXEC_ENABLE_EXTRA_TYPE_CHECKING
+#define STDEXEC_ENABLE_EXTRA_TYPE_CHECKING() 1
+#endif
+
 namespace stdexec
 {}
diff --git a/include/sdbusplus/async/stdexec/__detail/__execution_fwd.hpp b/include/sdbusplus/async/stdexec/__detail/__execution_fwd.hpp
index 31148a4..898c636 100644
--- a/include/sdbusplus/async/stdexec/__detail/__execution_fwd.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__execution_fwd.hpp
@@ -21,6 +21,10 @@
 
 namespace stdexec
 {
+struct __none_such;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+struct default_domain;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 namespace __receivers
@@ -48,8 +52,10 @@
 namespace __env
 {
 struct get_env_t;
-}
+struct empty_env;
+} // namespace __env
 
+using __env::empty_env;
 using __env::get_env_t;
 extern const get_env_t get_env;
 
@@ -119,10 +125,6 @@
 using __get_completion_signatures::get_completion_signatures_t;
 extern const get_completion_signatures_t get_completion_signatures;
 
-template <class _Sender, class _Env>
-using __completion_signatures_of_t =
-    __call_result_t<get_completion_signatures_t, _Sender, _Env>;
-
 //////////////////////////////////////////////////////////////////////////////////////////////////
 namespace __connect
 {
@@ -169,4 +171,41 @@
 using __as_awaitable::as_awaitable_t;
 extern const as_awaitable_t as_awaitable;
 
+//////////////////////////////////////////////////////////////////////////////////////////////////
+namespace __transfer
+{
+struct transfer_t;
+}
+
+using __transfer::transfer_t;
+extern const transfer_t transfer;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+namespace __transfer_just
+{
+struct transfer_just_t;
+}
+
+using __transfer_just::transfer_just_t;
+extern const transfer_just_t transfer_just;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+namespace __bulk
+{
+struct bulk_t;
+}
+
+using __bulk::bulk_t;
+extern const bulk_t bulk;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+namespace __on_v2
+{
+struct on_t;
+}
+
+namespace v2
+{
+using __on_v2::on_t;
+}
 } // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__intrusive_queue.hpp b/include/sdbusplus/async/stdexec/__detail/__intrusive_queue.hpp
index edd0e88..2ea46b4 100644
--- a/include/sdbusplus/async/stdexec/__detail/__intrusive_queue.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__intrusive_queue.hpp
@@ -40,6 +40,10 @@
         __tail_(std::exchange(__other.__tail_, nullptr))
     {}
 
+    __intrusive_queue(_Item* __head, _Item* __tail) noexcept :
+        __head_(__head), __tail_(__tail)
+    {}
+
     __intrusive_queue& operator=(__intrusive_queue __other) noexcept
     {
         std::swap(__head_, __other.__head_);
@@ -70,11 +74,33 @@
         return __result;
     }
 
+    static __intrusive_queue make(_Item* __list) noexcept
+    {
+        __intrusive_queue __result{};
+        __result.__head_ = __list;
+        __result.__tail_ = __list;
+        if (__list == nullptr)
+        {
+            return __result;
+        }
+        while (__result.__tail_->*_Next != nullptr)
+        {
+            __result.__tail_ = __result.__tail_->*_Next;
+        }
+        return __result;
+    }
+
     [[nodiscard]] bool empty() const noexcept
     {
         return __head_ == nullptr;
     }
 
+    void clear() noexcept
+    {
+        __head_ = nullptr;
+        __tail_ = nullptr;
+    }
+
     [[nodiscard]] _Item* pop_front() noexcept
     {
         STDEXEC_ASSERT(!empty());
@@ -147,6 +173,111 @@
         __other.__head_ = nullptr;
     }
 
+    struct iterator
+    {
+        using difference_type = std::ptrdiff_t;
+        using value_type = _Item*;
+
+        _Item* __predecessor_ = nullptr;
+        _Item* __item_ = nullptr;
+
+        iterator() noexcept = default;
+
+        explicit iterator(_Item* __pred, _Item* __item) noexcept :
+            __predecessor_(__pred), __item_(__item)
+        {}
+
+        [[nodiscard]] _Item* operator*() const noexcept
+        {
+            STDEXEC_ASSERT(__item_ != nullptr);
+            return __item_;
+        }
+
+        [[nodiscard]] _Item** operator->() const noexcept
+        {
+            STDEXEC_ASSERT(__item_ != nullptr);
+            return &__item_;
+        }
+
+        iterator& operator++() noexcept
+        {
+            __predecessor_ = __item_;
+            if (__item_)
+            {
+                __item_ = __item_->*_Next;
+            }
+            return *this;
+        }
+
+        iterator operator++(int) noexcept
+        {
+            iterator __result = *this;
+            ++*this;
+            return __result;
+        }
+
+        friend bool operator==(const iterator&,
+                               const iterator&) noexcept = default;
+    };
+
+    [[nodiscard]] iterator begin() const noexcept
+    {
+        return iterator(nullptr, __head_);
+    }
+
+    [[nodiscard]] iterator end() const noexcept
+    {
+        return iterator(__tail_, nullptr);
+    }
+
+    void splice(iterator pos, __intrusive_queue& other, iterator first,
+                iterator last) noexcept
+    {
+        if (first == last)
+        {
+            return;
+        }
+        STDEXEC_ASSERT(first.__item_ != nullptr);
+        STDEXEC_ASSERT(last.__predecessor_ != nullptr);
+        if (other.__head_ == first.__item_)
+        {
+            other.__head_ = last.__item_;
+            if (other.__head_ == nullptr)
+            {
+                other.__tail_ = nullptr;
+            }
+        }
+        else
+        {
+            STDEXEC_ASSERT(first.__predecessor_ != nullptr);
+            first.__predecessor_->*_Next = last.__item_;
+            last.__predecessor_->*_Next = pos.__item_;
+        }
+        if (empty())
+        {
+            __head_ = first.__item_;
+            __tail_ = last.__predecessor_;
+        }
+        else
+        {
+            pos.__predecessor_->*_Next = first.__item_;
+            if (pos.__item_ == nullptr)
+            {
+                __tail_ = last.__predecessor_;
+            }
+        }
+    }
+
+    _Item* front() const noexcept
+    {
+        return __head_;
+    }
+
+    _Item* back() const noexcept
+    {
+        return __tail_;
+    }
+
   private:
     _Item* __head_ = nullptr;
     _Item* __tail_ = nullptr;
diff --git a/include/sdbusplus/async/stdexec/__detail/__meta.hpp b/include/sdbusplus/async/stdexec/__detail/__meta.hpp
index 698526e..d1f5fea 100644
--- a/include/sdbusplus/async/stdexec/__detail/__meta.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__meta.hpp
@@ -37,6 +37,7 @@
 {
     __ignore() = default;
 
+    STDEXEC_ATTRIBUTE((always_inline)) //
     constexpr __ignore(auto&&...) noexcept {}
 };
 
@@ -89,8 +90,8 @@
 template <class _Tp, class _Up>
 using __mfirst = _Tp;
 
-template <class _Tp, class _UXp>
-using __msecond = _UXp;
+template <class _Tp, class _Up>
+using __msecond = _Up;
 
 template <class _Tp>
 extern const __undefined<_Tp> __v;
@@ -117,6 +118,9 @@
 template <std::size_t _Np>
 using __make_indices = std::make_index_sequence<_Np>*;
 
+template <class... _Ts>
+using __indices_for = __make_indices<sizeof...(_Ts)>;
+
 template <class _Char>
 concept __mchar = __same_as<_Char, char>;
 
@@ -143,6 +147,17 @@
         return _Len;
     }
 
+    template <std::size_t... _Is>
+    constexpr bool __equal(__mstring __other, __indices<_Is...>) const noexcept
+    {
+        return ((__what_[_Is] == __other.__what_[_Is]) && ...);
+    }
+
+    constexpr bool operator==(__mstring __other) const noexcept
+    {
+        return __equal(__other, __make_indices<_Len>());
+    }
+
     const char __what_[_Len];
 };
 
@@ -153,10 +168,10 @@
 {
     return {_Str...};
 }
-#elif STDEXEC_NVHPC()
-// BUGBUG TODO This is to work around an unknown EDG bug
+#elif STDEXEC_NVHPC() && (__EDG_VERSION__ < 605)
+// This is to work around an unfiled (by me) EDG bug that fixed in build 605
 template <__mstring _Str>
-constexpr auto operator""__csz() noexcept
+constexpr const __mtypeof<_Str> operator""__csz() noexcept
 {
     return _Str;
 }
@@ -178,11 +193,15 @@
 template <class _What, class... _With>
 struct _ERROR_
 {
-    const _ERROR_& operator,(__msuccess) const noexcept;
+    _ERROR_ operator,(__msuccess) const noexcept;
 };
 
+template <__mstring _What>
+struct _WHAT_
+{};
+
 template <class _What, class... _With>
-using __mexception = const _ERROR_<_What, _With...>&;
+using __mexception = _ERROR_<_What, _With...>;
 
 template <class>
 extern __msuccess __ok_v;
@@ -194,21 +213,7 @@
 using __ok_t = decltype(__ok_v<_Ty>);
 
 template <class... _Ts>
-using __disp = const decltype((__msuccess(), ..., __ok_t<_Ts>()))&;
-
-template <bool _AllOK>
-struct __i
-{
-    template <template <class...> class _Fn, class... _Args>
-    using __g = _Fn<_Args...>;
-};
-
-template <>
-struct __i<false>
-{
-    template <template <class...> class, class... _Args>
-    using __g = __disp<_Args...>;
-};
+using __disp = decltype((__msuccess(), ..., __ok_t<_Ts>()));
 
 template <class _Arg>
 concept __ok = __same_as<__ok_t<_Arg>, __msuccess>;
@@ -219,6 +224,9 @@
 template <class... _Args>
 concept _Ok = (__ok<_Args> && ...);
 
+template <bool _AllOK>
+struct __i;
+
 #if STDEXEC_NVHPC()
 // Most compilers memoize alias template specializations, but
 // nvc++ does not. So we memoize the type computations by
@@ -240,15 +248,52 @@
 template <template <class...> class _Fn, class... _Args>
 using __meval = __t<__meval_<_Fn, _Args...>>;
 
+template <class _Fn, class... _Args>
+using __minvoke__ = typename __i<_Ok<_Fn>>::template __h<_Fn, _Args...>;
+
+template <class _Fn, class... _Args>
+struct __minvoke_
+{};
+
+template <class _Fn, class... _Args>
+    requires __typename<__minvoke__<_Fn, _Args...>>
+struct __minvoke_<_Fn, _Args...>
+{
+    using __t = __minvoke__<_Fn, _Args...>;
+};
+
+template <class _Fn, class... _Args>
+using __minvoke = __t<__minvoke_<_Fn, _Args...>>;
+
 #else
 
 template <template <class...> class _Fn, class... _Args>
 using __meval = typename __i<_Ok<_Args...>>::template __g<_Fn, _Args...>;
 
+template <class _Fn, class... _Args>
+using __minvoke = typename __i<_Ok<_Fn>>::template __h<_Fn, _Args...>;
+
 #endif
 
-template <class _Fn, class... _Args>
-using __minvoke = __meval<_Fn::template __f, _Args...>;
+template <bool _AllOK>
+struct __i
+{
+    template <template <class...> class _Fn, class... _Args>
+    using __g = _Fn<_Args...>;
+
+    template <class _Fn, class... _Args>
+    using __h = __meval<_Fn::template __f, _Args...>;
+};
+
+template <>
+struct __i<false>
+{
+    template <template <class...> class, class... _Args>
+    using __g = __disp<_Args...>;
+
+    template <class _Fn, class...>
+    using __h = _Fn;
+};
 
 template <template <class...> class _Fn>
 struct __q
@@ -278,13 +323,13 @@
 using __mbind_back = __mbind_back_q<_Fn::template __f, _Back...>;
 
 template <template <class...> class _Tp, class... _Args>
-concept __valid = requires { typename __meval<_Tp, _Args...>; };
+concept __mvalid = requires { typename __meval<_Tp, _Args...>; };
 
 template <class _Fn, class... _Args>
-concept __minvocable = __valid<_Fn::template __f, _Args...>;
+concept __minvocable = __mvalid<_Fn::template __f, _Args...>;
 
 template <template <class...> class _Tp, class... _Args>
-concept __msucceeds = __valid<_Tp, _Args...> && __ok<__meval<_Tp, _Args...>>;
+concept __msucceeds = __mvalid<_Tp, _Args...> && __ok<__meval<_Tp, _Args...>>;
 
 template <class _Fn, class... _Args>
 concept __minvocable_succeeds = __minvocable<_Fn, _Args...> &&
@@ -313,6 +358,12 @@
 struct __mdefer : __mdefer_<_Fn, _Args...>
 {};
 
+template <class _Fn, class... _Args>
+using __mmemoize = __t<__mdefer<_Fn, _Args...>>;
+
+template <template <class...> class _Fn, class... _Args>
+using __mmemoize_q = __mmemoize<__q<_Fn>, _Args...>;
+
 struct __if_
 {
     template <bool>
@@ -341,6 +392,12 @@
     requires(sizeof...(_False) <= 1)
 using __if_c = __minvoke<__if_::__<_Pred>, _True, _False...>;
 
+template <class _Pred, class _True, class... _False>
+using __minvoke_if = __minvoke<__if<_Pred, _True, _False...>>;
+
+template <bool _Pred, class _True, class... _False>
+using __minvoke_if_c = __minvoke<__if_c<_Pred, _True, _False...>>;
+
 template <class _Tp>
 struct __mconst
 {
@@ -348,25 +405,6 @@
     using __f = _Tp;
 };
 
-template <template <class...> class _Try, class _Catch>
-struct __mtry_catch_q
-{
-    template <class... _Args>
-    using __f =
-        __minvoke<__if_c<__valid<_Try, _Args...>, __q<_Try>, _Catch>, _Args...>;
-};
-
-template <class _Try, class _Catch>
-struct __mtry_catch
-{
-    template <class... _Args>
-    using __f =
-        __minvoke<__if_c<__minvocable<_Try, _Args...>, _Try, _Catch>, _Args...>;
-};
-
-template <class _Fn, class _Default>
-using __with_default = __mtry_catch<_Fn, __mconst<_Default>>;
-
 inline constexpr __mstring __mbad_substitution =
     "The specified meta-function could not be evaluated with the types provided."__csz;
 
@@ -375,8 +413,7 @@
 {};
 
 template <class... _Args>
-struct _WITH_TYPES_
-{};
+struct _WITH_TYPES_;
 
 template <template <class...> class _Fun>
 struct _WITH_META_FUNCTION_T_
@@ -394,6 +431,34 @@
                              _WITH_TYPES_<_Args...>>;
 };
 
+template <template <class...> class _Try, class _Catch>
+struct __mtry_catch_q
+{
+    template <class... _Args>
+    using __f = __minvoke<__if_c<__mvalid<_Try, _Args...>, __q<_Try>, _Catch>,
+                          _Args...>;
+};
+
+template <class _Try, class _Catch>
+struct __mtry_catch
+{
+    template <class... _Args>
+    using __f =
+        __minvoke<__if_c<__minvocable<_Try, _Args...>, _Try, _Catch>, _Args...>;
+};
+
+template <class _Fn, class _Default>
+using __with_default = __mtry_catch<_Fn, __mconst<_Default>>;
+
+template <template <class...> class _Fn, class _Default>
+using __with_default_q = __mtry_catch_q<_Fn, __mconst<_Default>>;
+
+template <class _Fn, class _Default, class... _Args>
+using __minvoke_or = __minvoke<__with_default<_Fn, _Default>, _Args...>;
+
+template <template <class...> class _Fn, class _Default, class... _Args>
+using __meval_or = __minvoke<__with_default_q<_Fn, _Default>, _Args...>;
+
 template <template <class...> class _Fn>
 struct __mtry_eval_
 {
@@ -657,8 +722,11 @@
 template <class... _As>
     requires(sizeof...(_As) == 1)
 using __msingle = __mfront<_As...>;
-template <class _Ty>
-using __msingle_or = __mbind_back_q<__mfront_, _Ty>;
+template <class _Default, class... _As>
+    requires(sizeof...(_As) <= 1)
+using __msingle_or_ = __mfront<_As..., _Default>;
+template <class _Default>
+using __msingle_or = __mbind_front_q<__msingle_or_, _Default>;
 
 template <class _Continuation = __q<__types>>
 struct __pop_front
@@ -711,8 +779,8 @@
 template <class _Ty>
 using __id = __minvoke<__id_<__has_id<_Ty>>, _Ty>;
 
-template <class _Ty>
-using __cvref_t = __copy_cvref_t<_Ty, __t<std::remove_cvref_t<_Ty>>>;
+template <class _From, class _To = __decay_t<_From>>
+using __cvref_t = __copy_cvref_t<_From, __t<_To>>;
 
 template <class _From, class _To = __decay_t<_From>>
 using __cvref_id = __copy_cvref_t<_From, __id<_To>>;
@@ -730,6 +798,23 @@
 using __call_result_t = decltype(__declval<_Fun>()(__declval<_As>()...));
 #endif
 
+template <const auto& _Fun, class... _As>
+using __result_of = __call_result_t<decltype(_Fun), _As...>;
+
+#if STDEXEC_CLANG() && (__clang_major__ < 13)
+template <class _Ty>
+constexpr auto __hide_ = [] { return (__mtype<_Ty>(*)())0; };
+#else
+template <class _Ty>
+extern decltype([] { return (__mtype<_Ty>(*)())0; }) __hide_;
+#endif
+
+template <class _Ty>
+using __hide = decltype(__hide_<_Ty>);
+
+template <class _Id>
+using __unhide = __t<__call_result_t<__call_result_t<_Id>>>;
+
 // For working around clang's lack of support for CWG#2369:
 // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2369
 struct __qcall_result
@@ -888,9 +973,9 @@
     using __f = __mor<__minvoke<_Fn, _Args>...>;
 };
 
-#if __has_builtin(__type_pack_element)
+#if STDEXEC_HAS_BUILTIN(__type_pack_element)
 template <std::size_t _Np, class... _Ts>
-using __m_at = __type_pack_element<_Np, _Ts...>;
+using __m_at_c = __type_pack_element<_Np, _Ts...>;
 #else
 template <std::size_t>
 using __void_ptr = void*;
@@ -911,13 +996,46 @@
 };
 
 template <std::size_t _Np, class... _Ts>
-using __m_at = __minvoke<__m_at_<std::make_index_sequence<_Np>>, _Ts...>;
+using __m_at_c = __minvoke<__m_at_<std::make_index_sequence<_Np>>, _Ts...>;
 #endif
 
+template <class _Np, class... _Ts>
+using __m_at = __m_at_c<__v<_Np>, _Ts...>;
+
+template <class... _Ts>
+using __mback = __m_at_c<sizeof...(_Ts) - 1, _Ts...>;
+
+template <class _Continuation = __q<__types>>
+struct __mpop_back
+{
+    template <class>
+    struct __impl;
+
+    template <std::size_t... _Idx>
+    struct __impl<__indices<_Idx...>>
+    {
+        template <class... _Ts>
+        using __f = __minvoke<_Continuation, __m_at_c<_Idx, _Ts...>...>;
+    };
+
+    template <class... _Ts>
+        requires(sizeof...(_Ts) != 0)
+    using __f = __minvoke<__impl<__make_indices<sizeof...(_Ts) - 1>>, _Ts...>;
+};
+
 template <std::size_t _Np>
-struct __placeholder_;
-template <std::size_t _Np>
-using __placeholder = __placeholder_<_Np>*;
+struct __placeholder
+{
+    __placeholder() = default;
+
+    constexpr __placeholder(void*) noexcept {}
+
+    friend constexpr std::size_t
+        __get_placeholder_offset(__placeholder) noexcept
+    {
+        return _Np;
+    }
+};
 
 using __0 = __placeholder<0>;
 using __1 = __placeholder<1>;
@@ -939,25 +1057,78 @@
 template <template <class...> class _Cp, class _Noexcept = __mbool<true>>
 using __mconstructor_for = __mcompose<__q<__mconstruct>, __q<_Cp>>;
 
+#if STDEXEC_MSVC()
+// MSVCBUG
+// https://developercommunity.visualstudio.com/t/Incorrect-function-template-argument-sub/10437827
+
+template <std::size_t>
+struct __ignore_t
+{
+    __ignore_t() = default;
+
+    constexpr __ignore_t(auto&&...) noexcept {}
+};
+#else
 template <std::size_t>
 using __ignore_t = __ignore;
+#endif
 
-template <std::size_t... _Is, class _Ty, class... _Us>
-_Ty&& __nth_pack_element_(__ignore_t<_Is>..., _Ty&& __t, _Us&&...) noexcept
+template <class... _Ignore>
+struct __nth_pack_element_impl
 {
-    return (_Ty&&)__t;
-}
+    template <class _Ty, class... _Us>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+    constexpr _Ty&& operator()(_Ignore..., _Ty&& __t, _Us&&...) const noexcept
+    {
+        return (decltype(__t)&&)__t;
+    }
+};
 
-template <std::size_t _Np, class... _Ts>
-constexpr decltype(auto) __nth_pack_element(_Ts&&... __ts) noexcept
+template <std::size_t _Np>
+struct __nth_pack_element_t
 {
-    return [&]<std::size_t... _Is>(
-               std::index_sequence<_Is...>*) noexcept -> decltype(auto) {
-        return stdexec::__nth_pack_element_<_Is...>((_Ts&&)__ts...);
-    }((std::make_index_sequence<_Np>*)nullptr);
-}
+    template <std::size_t... _Is>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+    static constexpr auto __impl(__indices<_Is...>) noexcept
+    {
+        return __nth_pack_element_impl<__ignore_t<_Is>...>();
+    }
 
-template <class _Ty>
+    template <class... _Ts>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+    constexpr decltype(auto) operator()(_Ts&&... __ts) const noexcept
+    {
+        static_assert(_Np < sizeof...(_Ts));
+        return __impl(__make_indices<_Np>())((_Ts&&)__ts...);
+    }
+};
+
+template <std::size_t _Np>
+inline constexpr __nth_pack_element_t<_Np> __nth_pack_element{};
+
+template <auto... _Vs>
+struct __mliterals
+{
+    template <std::size_t _Np>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+    static constexpr auto __nth() noexcept
+    {
+        return stdexec::__nth_pack_element<_Np>(_Vs...);
+    }
+};
+
+template <std::size_t _Np>
+struct __nth_member
+{
+    template <class _Ty>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+    constexpr decltype(auto) operator()(_Ty && __ty) const noexcept
+    {
+        return ((_Ty&&)__ty).*(__ty.__mbrs_.template __nth<_Np>());
+    }
+};
+
+template <class _Ty, std::size_t _Offset = 0>
 struct __mdispatch_
 {
     template <class... _Ts>
@@ -967,60 +1138,131 @@
     }
 };
 
-template <std::size_t _Np>
-struct __mdispatch_<__placeholder<_Np>>
+template <std::size_t _Np, std::size_t _Offset>
+struct __mdispatch_<__placeholder<_Np>, _Offset>
 {
     template <class... _Ts>
     decltype(auto) operator()(_Ts&&... __ts) const noexcept
     {
-        return stdexec::__nth_pack_element<_Np>((_Ts&&)__ts...);
+        return stdexec::__nth_pack_element<_Np + _Offset>((_Ts&&)__ts...);
     }
 };
 
-template <std::size_t _Np>
-struct __mdispatch_<__placeholder<_Np>&>
+template <std::size_t _Np, std::size_t _Offset>
+struct __mdispatch_<__placeholder<_Np>&, _Offset>
 {
     template <class... _Ts>
     decltype(auto) operator()(_Ts&&... __ts) const noexcept
     {
-        return stdexec::__nth_pack_element<_Np>(__ts...);
+        return stdexec::__nth_pack_element<_Np + _Offset>(__ts...);
     }
 };
 
-template <std::size_t _Np>
-struct __mdispatch_<__placeholder<_Np>&&>
+template <std::size_t _Np, std::size_t _Offset>
+struct __mdispatch_<__placeholder<_Np>&&, _Offset>
 {
     template <class... _Ts>
     decltype(auto) operator()(_Ts&&... __ts) const noexcept
     {
-        return std::move(stdexec::__nth_pack_element<_Np>(__ts...));
+        return std::move(stdexec::__nth_pack_element<_Np + _Offset>(__ts...));
     }
 };
 
-template <std::size_t _Np>
-struct __mdispatch_<const __placeholder<_Np>&>
+template <std::size_t _Np, std::size_t _Offset>
+struct __mdispatch_<const __placeholder<_Np>&, _Offset>
 {
     template <class... _Ts>
     decltype(auto) operator()(_Ts&&... __ts) const noexcept
     {
-        return std::as_const(stdexec::__nth_pack_element<_Np>(__ts...));
+        return std::as_const(
+            stdexec::__nth_pack_element<_Np + _Offset>(__ts...));
     }
 };
 
-template <class _Ret, class... _Args>
-struct __mdispatch_<_Ret (*)(_Args...)>
+template <class _Ret, class... _Args, std::size_t _Offset>
+struct __mdispatch_<_Ret (*)(_Args...), _Offset>
 {
     template <class... _Ts>
-        requires(__callable<__mdispatch_<_Args>, _Ts...> && ...) &&
-                __callable<_Ret,
-                           __call_result_t<__mdispatch_<_Args>, _Ts...>...>
+        requires(__callable<__mdispatch_<_Args, _Offset>, _Ts...> && ...) &&
+                __callable<_Ret, __call_result_t<__mdispatch_<_Args, _Offset>,
+                                                 _Ts...>...>
+    auto operator()(_Ts&&... __ts) const noexcept(
+        __nothrow_callable<
+            _Ret, __call_result_t<__mdispatch_<_Args, _Offset>, _Ts...>...>)
+        -> __call_result_t<
+            _Ret, __call_result_t<__mdispatch_<_Args, _Offset>, _Ts...>...>
+    {
+        return _Ret{}(__mdispatch_<_Args, _Offset>{}((_Ts&&)__ts...)...);
+    }
+};
+
+template <class _Ret, class... _Args, std::size_t _Offset>
+struct __mdispatch_<_Ret (*)(_Args..., ...), _Offset>
+{
+    static_assert(_Offset == 0, "nested pack expressions are not supported");
+    using _Pattern = __mback<_Args...>;
+    static constexpr std::size_t __offset =
+        __get_placeholder_offset((__mtype<_Pattern>*)nullptr);
+
+    struct __impl
+    {
+        template <std::size_t... _Idx, class... _Ts>
+            requires(__callable<__mdispatch_<_Args>, _Ts...> && ...) &&
+                    (__callable<__mdispatch_<_Pattern, _Idx + 1>, _Ts...> &&
+                     ...) &&
+                    __callable< //
+                        _Ret, __call_result_t<__mdispatch_<_Args>, _Ts...>...,
+                        __call_result_t<__mdispatch_<_Pattern, _Idx + 1>,
+                                        _Ts...>...>
+        auto operator()(__indices<_Idx...>, _Ts&&... __ts) const noexcept(
+            __nothrow_callable<                                  //
+                _Ret,                                            //
+                __call_result_t<__mdispatch_<_Args>, _Ts...>..., //
+                __call_result_t<__mdispatch_<_Pattern, _Idx + 1>, _Ts...>...>)
+            -> __call_result_t<                                  //
+                _Ret, __call_result_t<__mdispatch_<_Args>, _Ts...>...,
+                __call_result_t<__mdispatch_<_Pattern, _Idx + 1>, _Ts...>...>
+        {
+            return _Ret()(                                //
+                __mdispatch_<_Args>()((_Ts&&)__ts...)..., //
+                __mdispatch_<_Pattern, _Idx + 1>()((_Ts&&)__ts...)...);
+        }
+    };
+
+    template <class... _Ts>
+        requires(__offset < sizeof...(_Ts)) &&
+                __callable<__impl,
+                           __make_indices<sizeof...(_Ts) - __offset - 1>,
+                           _Ts...>
+    auto operator()(_Ts&&... __ts) const noexcept(
+        __nothrow_callable<
+            __impl, __make_indices<sizeof...(_Ts) - __offset - 1>, _Ts...>)
+        -> __msecond<
+            __if_c<(__offset < sizeof...(_Ts))>,
+            __call_result_t<
+                __impl, __make_indices<sizeof...(_Ts) - __offset - 1>, _Ts...>>
+    {
+        return __impl()(__make_indices<sizeof...(_Ts) - __offset - 1>(),
+                        (_Ts&&)__ts...);
+    }
+
+    template <class... _Ts>
+        requires(sizeof...(_Ts) == __offset) &&
+                __callable<
+                    __mdispatch_<__minvoke<__mpop_back<__qf<_Ret>>, _Args...>*>,
+                    _Ts...>
     auto operator()(_Ts&&... __ts) const
         noexcept(__nothrow_callable<
-                 _Ret, __call_result_t<__mdispatch_<_Args>, _Ts...>...>)
-            -> __call_result_t<_Ret,
-                               __call_result_t<__mdispatch_<_Args>, _Ts...>...>
+                 __mdispatch_<__minvoke<__mpop_back<__qf<_Ret>>, _Args...>*>,
+                 _Ts...>)
+            -> __msecond<
+                __if_c<(sizeof...(_Ts) == __offset)>,
+                __call_result_t<
+                    __mdispatch_<__minvoke<__mpop_back<__qf<_Ret>>, _Args...>*>,
+                    _Ts...>>
     {
-        return _Ret{}(__mdispatch_<_Args>{}((_Ts&&)__ts...)...);
+        return __mdispatch_<__minvoke<__mpop_back<__qf<_Ret>>, _Args...>*>()(
+            (_Ts&&)__ts...);
     }
 };
 
@@ -1029,21 +1271,13 @@
 {};
 
 template <class _Ret, class... _Args>
-struct __mdispatch<_Ret(_Args...)>
-{
-    template <class... _Ts>
-        requires(__callable<__mdispatch_<_Args>, _Ts...> && ...) &&
-                __callable<_Ret,
-                           __call_result_t<__mdispatch_<_Args>, _Ts...>...>
-    auto operator()(_Ts&&... __ts) const
-        noexcept(__nothrow_callable<
-                 _Ret, __call_result_t<__mdispatch_<_Args>, _Ts...>...>)
-            -> __call_result_t<_Ret,
-                               __call_result_t<__mdispatch_<_Args>, _Ts...>...>
-    {
-        return _Ret{}(__mdispatch_<_Args>{}((_Ts&&)__ts...)...);
-    }
-};
+struct __mdispatch<_Ret(_Args...)> : __mdispatch_<_Ret (*)(_Args...)>
+{};
+
+template <class _Ret, class... _Args>
+struct __mdispatch<_Ret(_Args..., ...)> : __mdispatch_<_Ret (*)(_Args..., ...)>
+{};
+
 template <class _Ty, class... _Ts>
 concept __dispatchable = __callable<__mdispatch<_Ty>, _Ts...>;
 
@@ -1073,8 +1307,7 @@
 
 template <class _Signatures, class _DefaultFn, class... _Args>
 using __make_dispatcher = //
-    __minvoke<
-        __if_c<__minvocable<__which<_Signatures>, _Args...>,
-               __mcompose<__q<__mdispatch>, __which<_Signatures>>, _DefaultFn>,
-        _Args...>;
+    __minvoke<__mtry_catch<__mcompose<__q<__mdispatch>, __which<_Signatures>>,
+                           _DefaultFn>,
+              _Args...>;
 } // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__p2300.hpp b/include/sdbusplus/async/stdexec/__detail/__p2300.hpp
index 56057ba..e7a2c18 100644
--- a/include/sdbusplus/async/stdexec/__detail/__p2300.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__p2300.hpp
@@ -100,7 +100,10 @@
     stdexec::stop_token_of_t<_StopTokenProvider>;
 
 // [exec.env], execution environments
-using no_env STDEXEC_STD_DEPRECATED = stdexec::no_env;
+struct __no_env
+{};
+
+using no_env STDEXEC_STD_DEPRECATED = __no_env;
 using get_env_t STDEXEC_STD_DEPRECATED = stdexec::get_env_t;
 // using forwarding_env_query_t STDEXEC_STD_DEPRECATED =
 // stdexec::forwarding_env_query_t; // BUGBUG
@@ -155,14 +158,14 @@
 inline constexpr stdexec::start_t start{};
 
 // [exec.snd], senders
-template <class _Sender, class _Env = stdexec::no_env>
+template <class _Sender, class _Env = __no_env>
 concept sender /*STDEXEC_STD_DEPRECATED*/ = stdexec::sender_in<_Sender, _Env>;
 
 template <class _Sender, class _Receiver>
 concept sender_to /*STDEXEC_STD_DEPRECATED*/ =
     stdexec::sender_to<_Sender, _Receiver>;
 
-template <class _Sender, class _SetSig, class _Env = stdexec::no_env>
+template <class _Sender, class _SetSig, class _Env = __no_env>
 concept sender_of /*STDEXEC_STD_DEPRECATED*/ =
     stdexec::sender_of<_Sender, _SetSig, _Env>;
 
@@ -173,30 +176,34 @@
 inline constexpr stdexec::get_completion_signatures_t
     get_completion_signatures{};
 
-template <class _Sender, class _Env = stdexec::no_env>
+template <class _Sender, class _Env = __no_env>
 using completion_signatures_of_t STDEXEC_STD_DEPRECATED =
     stdexec::completion_signatures_of_t<_Sender, _Env>;
 
 template <class _Env>
+struct __dependent_completion_signatures
+{};
+
+template <class _Env>
 using dependent_completion_signatures STDEXEC_STD_DEPRECATED =
-    stdexec::dependent_completion_signatures<_Env>;
+    __dependent_completion_signatures<_Env>;
 
 template <                                                       //
     class _Sender,                                               //
-    class _Env = stdexec::no_env,                                //
+    class _Env = __no_env,                                       //
     template <class...> class _Tuple = stdexec::__decayed_tuple, //
     template <class...> class _Variant = stdexec::__variant>
 using value_types_of_t STDEXEC_STD_DEPRECATED =
     stdexec::value_types_of_t<_Sender, _Env, _Tuple, _Variant>;
 
-template <                        //
-    class _Sender,                //
-    class _Env = stdexec::no_env, //
+template <                 //
+    class _Sender,         //
+    class _Env = __no_env, //
     template <class...> class _Variant = stdexec::__variant>
 using error_types_of_t STDEXEC_STD_DEPRECATED =
     stdexec::error_types_of_t<_Sender, _Env, _Variant>;
 
-template <class _Sender, class _Env = stdexec::no_env>
+template <class _Sender, class _Env = __no_env>
 STDEXEC_STD_DEPRECATED inline constexpr bool sends_stopped =
     stdexec::sends_stopped<_Sender, _Env>;
 
@@ -325,7 +332,7 @@
 // [exec.utils.mkcmplsigs]
 template <                                                        //
     class _Sender,                                                //
-    class _Env = stdexec::no_env,
+    class _Env = __no_env,
     class _Sigs = stdexec::completion_signatures<>,               //
     template <class...>
     class _SetValue = stdexec::__compl_sigs::__default_set_value, //
diff --git a/include/sdbusplus/async/stdexec/__detail/__ranges.hpp b/include/sdbusplus/async/stdexec/__detail/__ranges.hpp
new file mode 100644
index 0000000..f18f84a
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__ranges.hpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2023 NVIDIA Corporation
+ *
+ * Licensed under the Apache License Version 2.0 with LLVM Exceptions
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *   https://llvm.org/LICENSE.txt
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "__config.hpp"
+#include "__type_traits.hpp"
+
+#if 0 // STDEXEC_HAS_STD_RANGES()
+
+#include <ranges>
+
+namespace stdexec::ranges {
+  using std::ranges::begin;
+  using std::ranges::end;
+
+  using std::ranges::range_value_t;
+  using std::ranges::range_reference_t;
+  using std::ranges::iterator_t;
+  using std::ranges::sentinel_t;
+}
+
+#else
+
+#include <iterator>
+
+namespace stdexec::ranges
+{
+
+namespace __detail
+{
+void begin();
+void end();
+
+template <class _Ty>
+concept __has_member_begin = requires(_Ty&& __v) { ((_Ty&&)__v).begin(); };
+
+template <class _Ty>
+concept __has_free_begin = __has_member_begin<_Ty> ||
+                           requires(_Ty&& __v) { begin(((_Ty&&)__v)); };
+
+template <class _Ty>
+concept __has_member_end = requires(_Ty&& __v) { ((_Ty&&)__v).end(); };
+
+template <class _Ty>
+concept __has_free_end = __has_member_end<_Ty> ||
+                         requires(_Ty&& __v) { end(((_Ty&&)__v)); };
+
+struct __begin_t
+{
+    template <class _Range>
+        requires __has_member_begin<_Range>
+    auto operator()(_Range&& __rng) const
+        noexcept(noexcept(((_Range&&)__rng).begin()))
+            -> decltype(((_Range&&)__rng).begin())
+    {
+        return ((_Range&&)__rng).begin();
+    }
+
+    template <class _Range>
+        requires __has_free_begin<_Range>
+    auto operator()(_Range&& __rng) const
+        noexcept(noexcept(begin(((_Range&&)__rng))))
+            -> decltype(begin(((_Range&&)__rng)))
+    {
+        return begin(((_Range&&)__rng));
+    }
+};
+
+struct __end_t
+{
+    template <class _Range>
+        requires __has_member_end<_Range>
+    auto operator()(_Range&& __rng) const
+        noexcept(noexcept(((_Range&&)__rng).end()))
+            -> decltype(((_Range&&)__rng).end())
+    {
+        return ((_Range&&)__rng).end();
+    }
+
+    template <class _Range>
+        requires __has_free_end<_Range>
+    auto operator()(_Range&& __rng) const
+        noexcept(noexcept(end(((_Range&&)__rng))))
+            -> decltype(end(((_Range&&)__rng)))
+    {
+        return end(((_Range&&)__rng));
+    }
+};
+} // namespace __detail
+
+inline constexpr __detail::__begin_t begin{};
+inline constexpr __detail::__end_t end{};
+
+template <class _Range>
+using iterator_t = decltype(begin((__declval<_Range>())));
+
+template <class _Range>
+using sentinel_t = decltype(end((__declval<_Range>())));
+
+template <class _Range>
+using range_reference_t = decltype(*begin((__declval<_Range>())));
+
+template <class _Range>
+using range_value_t =
+    typename std::iterator_traits<iterator_t<_Range>>::value_type;
+
+} // namespace stdexec::ranges
+
+#endif
diff --git a/include/sdbusplus/async/stdexec/__detail/__scope.hpp b/include/sdbusplus/async/stdexec/__detail/__scope.hpp
index 5ad6b93..ee1847d 100644
--- a/include/sdbusplus/async/stdexec/__detail/__scope.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__scope.hpp
@@ -26,8 +26,8 @@
 template <class _Fn>
 struct __scope_guard<_Fn>
 {
-    STDEXEC_NO_UNIQUE_ADDRESS _Fn __fn_;
-    STDEXEC_NO_UNIQUE_ADDRESS __immovable __hidden_{};
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Fn __fn_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) __immovable __hidden_{};
     bool __dismissed_{false};
 
     ~__scope_guard()
@@ -45,9 +45,9 @@
 template <class _Fn, class _T0>
 struct __scope_guard<_Fn, _T0>
 {
-    STDEXEC_NO_UNIQUE_ADDRESS _Fn __fn_;
-    STDEXEC_NO_UNIQUE_ADDRESS _T0 __t0_;
-    STDEXEC_NO_UNIQUE_ADDRESS __immovable __hidden_{};
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Fn __fn_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _T0 __t0_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) __immovable __hidden_{};
 
     bool __dismissed_{false};
 
@@ -66,10 +66,10 @@
 template <class _Fn, class _T0, class _T1>
 struct __scope_guard<_Fn, _T0, _T1>
 {
-    STDEXEC_NO_UNIQUE_ADDRESS _Fn __fn_;
-    STDEXEC_NO_UNIQUE_ADDRESS _T0 __t0_;
-    STDEXEC_NO_UNIQUE_ADDRESS _T1 __t1_;
-    STDEXEC_NO_UNIQUE_ADDRESS __immovable __hidden_{};
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Fn __fn_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _T0 __t0_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _T1 __t1_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) __immovable __hidden_{};
 
     bool __dismissed_{false};
 
@@ -88,11 +88,11 @@
 template <class _Fn, class _T0, class _T1, class _T2>
 struct __scope_guard<_Fn, _T0, _T1, _T2>
 {
-    STDEXEC_NO_UNIQUE_ADDRESS _Fn __fn_;
-    STDEXEC_NO_UNIQUE_ADDRESS _T0 __t0_;
-    STDEXEC_NO_UNIQUE_ADDRESS _T1 __t1_;
-    STDEXEC_NO_UNIQUE_ADDRESS _T2 __t2_;
-    STDEXEC_NO_UNIQUE_ADDRESS __immovable __hidden_{};
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Fn __fn_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _T0 __t0_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _T1 __t1_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _T2 __t2_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) __immovable __hidden_{};
 
     bool __dismissed_{false};
 
diff --git a/include/sdbusplus/async/stdexec/__detail/__type_traits.hpp b/include/sdbusplus/async/stdexec/__detail/__type_traits.hpp
index 93e303a..2ec69d6 100644
--- a/include/sdbusplus/async/stdexec/__detail/__type_traits.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__type_traits.hpp
@@ -179,4 +179,11 @@
 template <class _From, class _To>
 using __copy_cvref_t = typename __copy_cvref_fn<_From>::template __f<_To>;
 
+#if !STDEXEC_HAS_BUILTIN(__is_const)
+template <class>
+inline constexpr bool __is_const = false;
+template <class _Up>
+inline constexpr bool __is_const<const _Up> = true;
+#endif
+
 } // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/any_sender_of.hpp b/include/sdbusplus/async/stdexec/any_sender_of.hpp
index 391cd86..443b64c 100644
--- a/include/sdbusplus/async/stdexec/any_sender_of.hpp
+++ b/include/sdbusplus/async/stdexec/any_sender_of.hpp
@@ -15,7 +15,9 @@
  */
 #pragma once
 
-#include <sdbusplus/async/stdexec/execution.hpp>
+#include "../stdexec/execution.hpp"
+
+#include <sdbusplus/async/stdexec/sequence_senders.hpp>
 
 #include <cstddef>
 
@@ -33,8 +35,8 @@
     constexpr const _VTable* operator()(__mtype<_VTable>,
                                         __mtype<_Tp>) const noexcept
     {
-        return tag_invoke(__create_vtable_t{}, __mtype<_VTable>{},
-                          __mtype<_Tp>{});
+        return stdexec::tag_invoke(__create_vtable_t{}, __mtype<_VTable>{},
+                                   __mtype<_Tp>{});
     }
 };
 
@@ -207,7 +209,7 @@
     {
         static_assert(
             nothrow_tag_invocable<__delete_t, __mtype<_Tp>, _Storage&>);
-        tag_invoke(__delete_t{}, __mtype<_Tp>{}, __storage);
+        stdexec::tag_invoke(__delete_t{}, __mtype<_Tp>{}, __storage);
     }
 };
 
@@ -225,7 +227,8 @@
                                                    __mtype<_Tp>, _Storage&,
                                                    const _Storage&>)
     {
-        tag_invoke(__copy_construct_t{}, __mtype<_Tp>{}, __self, __from);
+        stdexec::tag_invoke(__copy_construct_t{}, __mtype<_Tp>{}, __self,
+                            __from);
     }
 };
 
@@ -241,8 +244,8 @@
     {
         static_assert(nothrow_tag_invocable<__move_construct_t, __mtype<_Tp>,
                                             _Storage&, _Storage&&>);
-        tag_invoke(__move_construct_t{}, __mtype<_Tp>{}, __self,
-                   (_Storage&&)__from);
+        stdexec::tag_invoke(__move_construct_t{}, __mtype<_Tp>{}, __self,
+                            (_Storage&&)__from);
     }
 };
 
@@ -441,7 +444,7 @@
             __default_storage_vtable((__vtable_t*)nullptr)};
         void* __object_pointer_{nullptr};
         alignas(__alignment) std::byte __buffer_[__buffer_size]{};
-        STDEXEC_NO_UNIQUE_ADDRESS _Allocator __allocator_{};
+        STDEXEC_ATTRIBUTE((no_unique_address)) _Allocator __allocator_{};
     };
 };
 
@@ -675,7 +678,7 @@
     const __vtable_t* __vtable_{__default_storage_vtable((__vtable_t*)nullptr)};
     void* __object_pointer_{nullptr};
     alignas(__alignment) std::byte __buffer_[__buffer_size]{};
-    STDEXEC_NO_UNIQUE_ADDRESS _Allocator __allocator_{};
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Allocator __allocator_{};
 };
 
 struct __empty_vtable
@@ -779,7 +782,12 @@
     requires(__is_not_stop_token_query<_Queries> && ...)
 struct __ref<completion_signatures<_Sigs...>, _Queries...>
 {
+#if !STDEXEC_MSVC()
+    // MSVCBUG
+    // https://developercommunity.visualstudio.com/t/Private-member-inaccessible-when-used-in/10448363
+
   private:
+#endif
     using __vtable_t =
         stdexec::__t<__vtable<completion_signatures<_Sigs...>, _Queries...>>;
 
@@ -851,7 +859,12 @@
     requires(__is_stop_token_query<_Queries> || ...)
 struct __ref<completion_signatures<_Sigs...>, _Queries...>
 {
+#if !STDEXEC_MSVC()
+    // MSVCBUG
+    // https://developercommunity.visualstudio.com/t/Private-member-inaccessible-when-used-in/10448363
+
   private:
+#endif
     using _FilteredQueries =
         __minvoke<__remove_if<__q<__is_never_stop_token_query>>, _Queries...>;
     using __vtable_t = stdexec::__t<
@@ -944,7 +957,7 @@
 template <class _Receiver>
 struct __operation_base
 {
-    STDEXEC_NO_UNIQUE_ADDRESS _Receiver __rcvr_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Receiver __rcvr_;
     stdexec::in_place_stop_source __stop_source_{};
     using __stop_callback = typename stdexec::stop_token_of_t<
         stdexec::env_of_t<_Receiver>>::template callback_type<__on_stop_t>;
@@ -962,8 +975,17 @@
 
     struct __t
     {
+        using is_receiver = void;
         __operation_base<_Receiver>* __op_;
 
+        template <same_as<set_next_t> _SetNext, same_as<__t> _Self, class _Item>
+            requires __callable<_SetNext, _Receiver&, _Item>
+        friend auto tag_invoke(_SetNext, _Self& __self, _Item&& __item)
+        {
+            return _SetNext{}(__self.__op_->__rcvr_,
+                              static_cast<_Item&&>(__item));
+        }
+
         template <same_as<set_value_t> _SetValue, same_as<__t> _Self,
                   class... _Args>
             requires __callable<_SetValue, _Receiver&&, _Args...>
@@ -998,10 +1020,9 @@
         friend __env_t<env_of_t<_Receiver>>
             tag_invoke(_GetEnv, const _Self& __self) noexcept
         {
-            return __make_env(
-                get_env(__self.__op_->__rcvr_),
-                __with_(get_stop_token,
-                        __self.__op_->__stop_source_.get_token()));
+            return __make_env(get_env(__self.__op_->__rcvr_),
+                              __mkprop(__self.__op_->__stop_source_.get_token(),
+                                       get_stop_token));
         }
     };
 };
@@ -1058,7 +1079,7 @@
         {}
 
       private:
-        STDEXEC_NO_UNIQUE_ADDRESS _Receiver __rec_;
+        STDEXEC_ATTRIBUTE((no_unique_address)) _Receiver __rec_;
         __immovable_operation_storage __storage_{};
 
         friend void tag_invoke(start_t, __t& __self) noexcept
@@ -1330,7 +1351,8 @@
         std::is_nothrow_invocable_v<
             _Tag, stdexec::__copy_cvref_t<Self, __receiver_base>, _As...>)
     {
-        return tag_invoke(_Tag{}, ((Self&&)__self).__receiver_, (_As&&)__as...);
+        return stdexec::tag_invoke(_Tag{}, ((Self&&)__self).__receiver_,
+                                   (_As&&)__as...);
     }
 
   public:
@@ -1363,8 +1385,8 @@
             std::is_nothrow_invocable_v<
                 _Tag, stdexec::__copy_cvref_t<Self, __sender_base>, _As...>)
         {
-            return tag_invoke(_Tag{}, ((Self&&)__self).__sender_,
-                              (_As&&)__as...);
+            return stdexec::tag_invoke(_Tag{}, ((Self&&)__self).__sender_,
+                                       (_As&&)__as...);
         }
 
       public:
@@ -1405,9 +1427,21 @@
                     stdexec::get_completion_scheduler_t<stdexec::set_value_t>>>,
                 decltype(_SenderQueries)...>;
 
+#if STDEXEC_MSVC()
+            // MSVCBUG
+            // https://developercommunity.visualstudio.com/t/ICE-and-non-ICE-bug-in-NTTP-argument-w/10361081
+
+            static constexpr auto __any_scheduler_noexcept_signature =
+                stdexec::get_completion_scheduler<stdexec::set_value_t>.signature<any_scheduler() noexcept>;
+            template <class... _Queries>
+            using __schedule_sender_fn =
+                typename __schedule_receiver::template any_sender<
+                    __any_scheduler_noexcept_signature>;
+#else
             template <class... _Queries>
             using __schedule_sender_fn = typename __schedule_receiver::template any_sender<
                 stdexec::get_completion_scheduler<stdexec::set_value_t>.template signature<any_scheduler() noexcept>>;
+#endif
             using __schedule_sender =
                 stdexec::__mapply<stdexec::__q<__schedule_sender_fn>,
                                   schedule_sender_queries>;
@@ -1440,8 +1474,8 @@
                     _Tag, stdexec::__copy_cvref_t<Self, __scheduler_base>,
                     _As...>)
             {
-                return tag_invoke(_Tag{}, ((Self&&)__self).__scheduler_,
-                                  (_As&&)__as...);
+                return stdexec::tag_invoke(
+                    _Tag{}, ((Self&&)__self).__scheduler_, (_As&&)__as...);
             }
 
             friend bool
diff --git a/include/sdbusplus/async/stdexec/async_scope.hpp b/include/sdbusplus/async/stdexec/async_scope.hpp
index d806fc1..3da1840 100644
--- a/include/sdbusplus/async/stdexec/async_scope.hpp
+++ b/include/sdbusplus/async/stdexec/async_scope.hpp
@@ -62,7 +62,7 @@
 struct __when_empty_op_base : __task
 {
     using _Receiver = __t<_ReceiverId>;
-    STDEXEC_NO_UNIQUE_ADDRESS _Receiver __rcvr_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Receiver __rcvr_;
 };
 
 template <class _ConstrainedId, class _ReceiverId>
@@ -129,7 +129,10 @@
     template <__decays_to<__when_empty_sender> _Self, class _Env>
     friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
         -> completion_signatures_of_t<__copy_cvref_t<_Self, _Constrained>,
-                                      __env_t<_Env>>;
+                                      __env_t<_Env>>
+    {
+        return {};
+    }
 
     friend empty_env tag_invoke(get_env_t, const __when_empty_sender&) noexcept
     {
@@ -137,7 +140,7 @@
     }
 
     const __impl* __scope_;
-    STDEXEC_NO_UNIQUE_ADDRESS _Constrained __c_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Constrained __c_;
 };
 
 template <class _Constrained>
@@ -150,7 +153,7 @@
 {
     using _Receiver = __t<_ReceiverId>;
     const __impl* __scope_;
-    STDEXEC_NO_UNIQUE_ADDRESS _Receiver __rcvr_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Receiver __rcvr_;
 };
 
 template <class _ReceiverId>
@@ -238,7 +241,7 @@
     using is_sender = void;
 
     const __impl* __scope_;
-    STDEXEC_NO_UNIQUE_ADDRESS _Constrained __c_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Constrained __c_;
 
     template <class _Receiver>
     using __nest_operation_t = __nest_op<_ConstrainedId, __x<_Receiver>>;
@@ -254,10 +257,14 @@
         return __nest_operation_t<_Receiver>{
             __self.__scope_, ((_Self&&)__self).__c_, (_Receiver&&)__rcvr};
     }
+
     template <__decays_to<__nest_sender> _Self, class _Env>
     friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
         -> completion_signatures_of_t<__copy_cvref_t<_Self, _Constrained>,
-                                      __env_t<_Env>>;
+                                      __env_t<_Env>>
+    {
+        return {};
+    }
 
     friend empty_env tag_invoke(get_env_t, const __nest_sender&) noexcept
     {
@@ -393,9 +400,10 @@
         }
     }
 
-    STDEXEC_NO_UNIQUE_ADDRESS _Receiver __rcvr_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Receiver __rcvr_;
     std::unique_ptr<__future_state<_Sender, _Env>> __state_;
-    STDEXEC_NO_UNIQUE_ADDRESS __forward_consumer __forward_consumer_;
+    STDEXEC_ATTRIBUTE((no_unique_address))
+    __forward_consumer __forward_consumer_;
 
   public:
     ~__future_op() noexcept
@@ -683,7 +691,10 @@
 
     template <__decays_to<__future> _Self, class _OtherEnv>
     friend auto tag_invoke(get_completion_signatures_t, _Self&&, _OtherEnv&&)
-        -> __completions_t<_Self>;
+        -> __completions_t<_Self>
+    {
+        return {};
+    }
 
     friend empty_env tag_invoke(get_env_t, const __future&) noexcept
     {
@@ -699,11 +710,17 @@
 
 ////////////////////////////////////////////////////////////////////////////
 // async_scope::spawn implementation
+template <class _Env>
+using __spawn_env_t =
+    __result_of<__join_env, _Env,
+                __env::__prop<in_place_stop_token(get_stop_token_t)>,
+                __env::__prop<__inln::__scheduler(get_scheduler_t)>>;
+
 template <class _EnvId>
 struct __spawn_op_base
 {
     using _Env = __t<_EnvId>;
-    __env_t<_Env> __env_;
+    __spawn_env_t<_Env> __env_;
     void (*__delete_)(__spawn_op_base*);
 };
 
@@ -729,8 +746,8 @@
         std::terminate();
     }
 
-    friend const __env_t<_Env>& tag_invoke(get_env_t,
-                                           const __spawn_rcvr& __self) noexcept
+    friend const __spawn_env_t<_Env>&
+        tag_invoke(get_env_t, const __spawn_rcvr& __self) noexcept
     {
         return __self.__op_->__env_;
     }
@@ -748,8 +765,10 @@
     template <__decays_to<_Sender> _Sndr>
     __spawn_op(_Sndr&& __sndr, _Env __env, const __impl* __scope) :
         __spawn_op_base<_EnvId>{
-            make_env((_Env&&)__env,
-                     with(get_stop_token, __scope->__stop_source_.get_token())),
+            __join_env(
+                (_Env&&)__env,
+                __mkprop(__scope->__stop_source_.get_token(), get_stop_token),
+                __mkprop(__inln::__scheduler{}, get_scheduler)),
             [](__spawn_op_base<_EnvId>* __op) {
         delete static_cast<__spawn_op*>(__op);
     }},
@@ -802,7 +821,7 @@
     }
 
     template <__movable_value _Env = empty_env,
-              sender_in<__env_t<_Env>> _Sender>
+              sender_in<__spawn_env_t<_Env>> _Sender>
         requires sender_to<nest_result_t<_Sender>, __spawn_receiver_t<_Env>>
     void spawn(_Sender&& __sndr, _Env __env = {})
     {
diff --git a/include/sdbusplus/async/stdexec/at_coroutine_exit.hpp b/include/sdbusplus/async/stdexec/at_coroutine_exit.hpp
index dc6df2e..e0e6235 100644
--- a/include/sdbusplus/async/stdexec/at_coroutine_exit.hpp
+++ b/include/sdbusplus/async/stdexec/at_coroutine_exit.hpp
@@ -100,11 +100,10 @@
 
             template <__decays_to<__t> _Self, class _Env>
             friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
-                -> dependent_completion_signatures<_Env>;
-            template <__decays_to<__t> _Self, class _Env>
-            friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
                 -> __completion_signatures<_Env>
-                requires true;
+            {
+                return {};
+            }
 
             friend env_of_t<_Sender> tag_invoke(get_env_t,
                                                 const __t& __self) noexcept
@@ -194,8 +193,7 @@
             auto __coro = __p.__is_unhandled_stopped_
                               ? __p.continuation().unhandled_stopped()
                               : __p.continuation().handle();
-            __h.destroy();
-            return __coro;
+            return STDEXEC_DESTROY_AND_CONTINUE(__h, __coro);
         }
 
         void await_resume() const noexcept {}
diff --git a/include/sdbusplus/async/stdexec/commit.info b/include/sdbusplus/async/stdexec/commit.info
index 6c3c5cd..8556544 100644
--- a/include/sdbusplus/async/stdexec/commit.info
+++ b/include/sdbusplus/async/stdexec/commit.info
@@ -1 +1 @@
-f1409100e46d3bdf2cbf2d6fb6c8e4a96e8bd307
+6b027bc6b6ace7b9047656cf8eb6f934e0535da3
diff --git a/include/sdbusplus/async/stdexec/concepts.hpp b/include/sdbusplus/async/stdexec/concepts.hpp
index 3098123..a5ebe4a 100644
--- a/include/sdbusplus/async/stdexec/concepts.hpp
+++ b/include/sdbusplus/async/stdexec/concepts.hpp
@@ -101,7 +101,7 @@
 template <class T>
 concept destructible = __destructible_<T>;
 
-#if __has_builtin(__is_constructible)
+#if STDEXEC_HAS_BUILTIN(__is_constructible)
 template <class _Ty, class... _As>
 concept constructible_from = //
     destructible<_Ty> &&     //
@@ -110,7 +110,7 @@
 template <class _Ty, class... _As>
 concept constructible_from = //
     destructible<_Ty> &&     //
-    is_constructible_v<_Ty, _As...>;
+    std::is_constructible_v<_Ty, _As...>;
 #endif
 
 template <class _Ty>
@@ -232,7 +232,16 @@
     move_constructible<__decay_t<_Ty>> && //
     constructible_from<__decay_t<_Ty>, _Ty>;
 
-#if __has_builtin(__is_nothrow_constructible)
+template <class _Ty>
+concept __nothrow_movable_value = //
+    __movable_value<_Ty> &&       //
+    requires(_Ty&& __t) {
+        {
+            __decay_t<_Ty>{__decay_t<_Ty>{(_Ty&&)__t}}
+        } noexcept;
+    };
+
+#if STDEXEC_HAS_BUILTIN(__is_nothrow_constructible)
 template <class _Ty, class... _As>
 concept __nothrow_constructible_from = constructible_from<_Ty, _As...> &&
                                        __is_nothrow_constructible(_Ty, _As...);
@@ -257,8 +266,8 @@
 concept __nothrow_decay_copyable =
     __nothrow_constructible_from<__decay_t<_Ty>, _Ty>;
 
-template <class _Range>
-using range_value_t = decltype(*begin(::std::declval<_Range>()));
+template <class _Ty, class _Up>
+concept __decays_to_derived_from = derived_from<__decay_t<_Ty>, _Up>;
 
 } // namespace stdexec
 
diff --git a/include/sdbusplus/async/stdexec/coroutine.hpp b/include/sdbusplus/async/stdexec/coroutine.hpp
index 3c5c4c8..3391043 100644
--- a/include/sdbusplus/async/stdexec/coroutine.hpp
+++ b/include/sdbusplus/async/stdexec/coroutine.hpp
@@ -40,70 +40,89 @@
 template <class _Awaiter, class _Promise>
 concept __with_await_suspend =
     same_as<_Promise, void> || //
-    requires(_Awaiter& __await, __coro::coroutine_handle<_Promise> __h) {
+    requires(_Awaiter& __awaiter, __coro::coroutine_handle<_Promise> __h) {
         {
-            __await.await_suspend(__h)
+            __awaiter.await_suspend(__h)
         } -> __await_suspend_result;
     };
 
 template <class _Awaiter, class _Promise = void>
 concept __awaiter = //
-    requires(_Awaiter& __await) {
-        __await.await_ready() ? 1 : 0;
-        __await.await_resume();
+    requires(_Awaiter& __awaiter) {
+        __awaiter.await_ready() ? 1 : 0;
+        __awaiter.await_resume();
     } && //
     __with_await_suspend<_Awaiter, _Promise>;
 
+#if STDEXEC_MSVC()
+// MSVCBUG
+// https://developercommunity.visualstudio.com/t/operator-co_await-not-found-in-requires/10452721
+
 template <class _Awaitable>
-decltype(auto) __get_awaiter(_Awaitable&& __await, void*)
+void __co_await_constraint(_Awaitable&& __awaitable)
+    requires requires { operator co_await((_Awaitable&&)__awaitable); };
+#endif
+
+template <class _Awaitable>
+decltype(auto) __get_awaiter(_Awaitable&& __awaitable, void*)
 {
-    if constexpr (requires { ((_Awaitable&&)__await).operator co_await(); })
+    if constexpr (requires { ((_Awaitable&&)__awaitable).operator co_await(); })
     {
-        return ((_Awaitable&&)__await).operator co_await();
+        return ((_Awaitable&&)__awaitable).operator co_await();
     }
-    else if constexpr (requires { operator co_await((_Awaitable&&)__await); })
+    else if constexpr (requires {
+#if STDEXEC_MSVC()
+                           __co_await_constraint((_Awaitable&&)__awaitable);
+#else
+        operator co_await((_Awaitable&&) __awaitable);
+#endif
+                       })
     {
-        return operator co_await((_Awaitable&&)__await);
+        return operator co_await((_Awaitable&&)__awaitable);
     }
     else
     {
-        return (_Awaitable&&)__await;
+        return (_Awaitable&&)__awaitable;
     }
 }
 
 template <class _Awaitable, class _Promise>
-decltype(auto) __get_awaiter(_Awaitable&& __await, _Promise* __promise)
-    requires requires { __promise->await_transform((_Awaitable&&)__await); }
+decltype(auto) __get_awaiter(_Awaitable&& __awaitable, _Promise* __promise)
+    requires requires { __promise->await_transform((_Awaitable&&)__awaitable); }
 {
     if constexpr (requires {
-                      __promise->await_transform((_Awaitable&&)__await)
+                      __promise->await_transform((_Awaitable&&)__awaitable)
                           .
                           operator co_await();
                   })
     {
-        return __promise->await_transform((_Awaitable&&)__await)
+        return __promise->await_transform((_Awaitable&&)__awaitable)
             .
             operator co_await();
     }
     else if constexpr (requires {
-                           operator co_await(__promise->await_transform(
-                               (_Awaitable&&)__await));
+#if STDEXEC_MSVC()
+                           __co_await_constraint(__promise->await_transform(
+                               (_Awaitable&&)__awaitable));
+#else
+        operator co_await(__promise->await_transform((_Awaitable&&) __awaitable));
+#endif
                        })
     {
         return operator co_await(
-            __promise->await_transform((_Awaitable&&)__await));
+            __promise->await_transform((_Awaitable&&)__awaitable));
     }
     else
     {
-        return __promise->await_transform((_Awaitable&&)__await);
+        return __promise->await_transform((_Awaitable&&)__awaitable);
     }
 }
 
 template <class _Awaitable, class _Promise = void>
 concept __awaitable = //
-    requires(_Awaitable&& __await, _Promise* __promise) {
+    requires(_Awaitable&& __awaitable, _Promise* __promise) {
         {
-            stdexec::__get_awaiter((_Awaitable&&)__await, __promise)
+            stdexec::__get_awaiter((_Awaitable&&)__awaitable, __promise)
         } -> __awaiter<_Promise>;
     };
 
diff --git a/include/sdbusplus/async/stdexec/env.hpp b/include/sdbusplus/async/stdexec/env.hpp
index 0beaf08..68fe431 100644
--- a/include/sdbusplus/async/stdexec/env.hpp
+++ b/include/sdbusplus/async/stdexec/env.hpp
@@ -17,30 +17,29 @@
 
 #include "../stdexec/execution.hpp"
 
-#ifdef __EDG__
-#pragma diagnostic push
-#pragma diag_suppress 1302
-#endif
+STDEXEC_PRAGMA_PUSH()
+STDEXEC_PRAGMA_IGNORE_EDG(1302)
 
 namespace exec
 {
-template <class... _TagValue>
-using with_t = stdexec::__with<_TagValue...>;
+template <class _Tag, class _Value = void>
+using with_t = stdexec::__with<_Tag, _Value>;
 
 namespace __detail
 {
 struct __with_t
 {
     template <class _Tag, class _Value>
-    with_t<_Tag, _Value> operator()(_Tag, _Value&& __val) const
+    with_t<_Tag, stdexec::__decay_t<_Value>> operator()(_Tag,
+                                                        _Value&& __val) const
     {
-        return stdexec::__with_(_Tag(), (_Value&&)__val);
+        return stdexec::__mkprop((_Value&&)__val, _Tag());
     }
 
     template <class _Tag>
     with_t<_Tag> operator()(_Tag) const
     {
-        return stdexec::__with_(_Tag());
+        return stdexec::__mkprop(_Tag());
     }
 };
 } // namespace __detail
@@ -64,7 +63,7 @@
     using _Default = __t<_DefaultId>;
     using _Receiver = __t<_ReceiverId>;
 
-    STDEXEC_NO_UNIQUE_ADDRESS _Default __default_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Default __default_;
     _Receiver __rcvr_;
 
     friend void tag_invoke(start_t, __operation& __self) noexcept
@@ -94,7 +93,7 @@
 {
     using _Default = __t<_DefaultId>;
     using is_sender = void;
-    STDEXEC_NO_UNIQUE_ADDRESS _Default __default_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Default __default_;
 
     template <class _Env>
     using __value_t = __minvoke<
@@ -116,11 +115,12 @@
         return {{}, ((_Self&&)__self).__default_, (_Receiver&&)__rcvr};
     }
 
-    friend auto tag_invoke(get_completion_signatures_t, __sender, no_env)
-        -> dependent_completion_signatures<no_env>;
-    template <__none_of<no_env> _Env>
+    template <class _Env>
     friend auto tag_invoke(get_completion_signatures_t, __sender, _Env&&)
-        -> __completions_t<_Env>;
+        -> __completions_t<_Env>
+    {
+        return {};
+    }
 };
 
 struct __read_with_default_t
@@ -136,137 +136,7 @@
 
 inline constexpr __read_with_default::__read_with_default_t read_with_default{};
 
-namespace __write
-{
-using namespace stdexec;
-
-struct __write_t;
-
-template <class _ReceiverId, class _Env>
-struct __operation_base
-{
-    using _Receiver = __t<_ReceiverId>;
-    _Receiver __rcvr_;
-    const _Env __env_;
-};
-
-template <class _ReceiverId, class _Env>
-struct __receiver
-{
-    using _Receiver = stdexec::__t<_ReceiverId>;
-
-    struct __t : receiver_adaptor<__t>
-    {
-        _Receiver&& base() && noexcept
-        {
-            return (_Receiver&&)__op_->__rcvr_;
-        }
-
-        const _Receiver& base() const& noexcept
-        {
-            return __op_->__rcvr_;
-        }
-
-        auto get_env() const noexcept
-            -> __env::__env_join_t<const _Env&, env_of_t<_Receiver>>
-        {
-            return __env::__join_env(__op_->__env_, stdexec::get_env(base()));
-        }
-
-        __operation_base<_ReceiverId, _Env>* __op_;
-    };
-};
-
-template <class _SenderId, class _ReceiverId, class _Env>
-struct __operation : __operation_base<_ReceiverId, _Env>
-{
-    using _Sender = __t<_SenderId>;
-    using __base_t = __operation_base<_ReceiverId, _Env>;
-    using __receiver_t = __t<__receiver<_ReceiverId, _Env>>;
-    connect_result_t<_Sender, __receiver_t> __state_;
-
-    __operation(_Sender&& __sndr, auto&& __rcvr, auto&& __env) :
-        __base_t{(decltype(__rcvr))__rcvr, (decltype(__env))__env},
-        __state_{stdexec::connect((_Sender&&)__sndr, __receiver_t{{}, this})}
-    {}
-
-    friend void tag_invoke(start_t, __operation& __self) noexcept
-    {
-        start(__self.__state_);
-    }
-};
-
-template <class _SenderId, class _Env>
-struct __sender
-{
-    using _Sender = stdexec::__t<_SenderId>;
-
-    template <class _Receiver>
-    using __receiver_t = stdexec::__t<__receiver<__id<_Receiver>, _Env>>;
-    template <class _Self, class _Receiver>
-    using __operation_t = __operation<__id<__copy_cvref_t<_Self, _Sender>>,
-                                      __id<_Receiver>, _Env>;
-
-    struct __t
-    {
-        using is_sender = void;
-        using __id = __sender;
-        _Sender __sndr_;
-        _Env __env_;
-
-        template <__decays_to<__t> _Self, receiver _Receiver>
-            requires sender_to<__copy_cvref_t<_Self, _Sender>,
-                               __receiver_t<_Receiver>>
-        friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr)
-            -> __operation_t<_Self, _Receiver>
-        {
-            return {((_Self&&)__self).__sndr_, (_Receiver&&)__rcvr,
-                    ((_Self&&)__self).__env_};
-        }
-
-        friend auto tag_invoke(stdexec::get_env_t, const __t& __self) //
-            noexcept(
-                stdexec::__nothrow_callable<stdexec::get_env_t, const _Sender&>)
-                -> stdexec::env_of_t<const _Sender&>
-        {
-            return stdexec::get_env(__self.__sndr_);
-        }
-
-        template <__decays_to<__t> _Self, class _BaseEnv>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&, _BaseEnv&&)
-            -> stdexec::__completion_signatures_of_t<
-                __copy_cvref_t<_Self, _Sender>,
-                __env::__env_join_t<_Env, _BaseEnv>>;
-    };
-};
-
-struct __write_t
-{
-    template <class _Sender, class... _Funs>
-    using __sender_t =
-        __t<__sender<__id<__decay_t<_Sender>>,
-                     __env::__env_join_t<__env::__env_fn<_Funs>...>>>;
-
-    template <__is_not_instance_of<__env::__env_fn> _Sender, class... _Funs>
-        requires sender<_Sender>
-    auto operator()(_Sender&& __sndr, __env::__env_fn<_Funs>... __withs) const
-        -> __sender_t<_Sender, _Funs...>
-    {
-        return {(_Sender&&)__sndr, __env::__join_env(std::move(__withs)...)};
-    }
-
-    template <class... _Funs>
-    auto operator()(__env::__env_fn<_Funs>... __withs) const
-        -> __binder_back<__write_t, __env::__env_fn<_Funs>...>
-    {
-        return {{}, {}, {std::move(__withs)...}};
-    }
-};
-} // namespace __write
-
-inline constexpr __write::__write_t write{};
+inline constexpr stdexec::__write_::__write_t write{};
 } // namespace exec
 
-#ifdef __EDG__
-#pragma diagnostic pop
-#endif
+STDEXEC_PRAGMA_POP()
diff --git a/include/sdbusplus/async/stdexec/execution.hpp b/include/sdbusplus/async/stdexec/execution.hpp
index 1a81553..78a5fff 100644
--- a/include/sdbusplus/async/stdexec/execution.hpp
+++ b/include/sdbusplus/async/stdexec/execution.hpp
@@ -15,6 +15,7 @@
  */
 #pragma once
 
+#include "__detail/__basic_sender.hpp"
 #include "__detail/__execution_fwd.hpp"
 #include "__detail/__intrusive_ptr.hpp"
 #include "__detail/__meta.hpp"
@@ -37,53 +38,15 @@
 #include <type_traits>
 #include <variant>
 
-#ifdef __EDG__
-#pragma diagnostic push
-#pragma diag_suppress 1302
-#pragma diag_suppress 497
-#pragma diag_suppress type_qualifiers_ignored_on_reference
-#endif
-
-#ifndef STDEXEC_DISABLE_R5_DEPRECATION_WARNINGS
-#define STDEXEC_R5_SENDER_DEPRECATION_WARNING                                  \
-    [[deprecated(                                                              \
-        "Deprecated sender type detected. "                                    \
-        "Please give the type a nested `is_sender` type alias, or "            \
-        "specialize stdexec::enable_sender<your-sender-type> to be `true`. "   \
-        "To suppress this deprecation warning, define `STDEXEC_DISABLE_R5_DEPRECATIONS`.")]]
-#define STDEXEC_R5_RECEIVER_DEPRECATION_WARNING                                 \
-    [[deprecated(                                                               \
-        "Deprecated receiver type detected. "                                   \
-        "Please give the type a nested `is_receiver` type alias, or "           \
-        "specialize stdexec::enable_receiver<your-receiver-type> to be `true`." \
-        "To suppress this deprecation warning, define `STDEXEC_DISABLE_R5_DEPRECATIONS`.")]]
-#define STDEXEC_R5_DEPENDENT_COMPLETION_SIGNATURES_DEPRECATION_WARNING                 \
-    [[deprecated(                                                                      \
-        "The `dependent_completion_signatures<>` type is deprecated. There is "        \
-        "no need to define a customization of `get_completion_signatures` for "        \
-        "sender types whose completions are dependent on the receiver's environment. " \
-        "Give your sender type a nested `is_sender` type alias instead, "              \
-        "specialize stdexec::enable_sender<your-sender-type> to be `true`. "           \
-        "To suppress this deprecation warning, define `STDEXEC_DISABLE_R5_DEPRECATIONS`.")]]
-#define STDEXEC_R5_NO_ENV_DEPRECATION_WARNING                                          \
-    [[deprecated(                                                                      \
-        "The `no_env` type is deprecated. The stdexec library no longer needs to use " \
-        "it to probe a type for satisfaction of the `sender` concept. "                \
-        "Give your sender type a nested `is_sender` type alias instead, or "           \
-        "specialize stdexec::enable_sender<your-sender-type> to be `true`. "           \
-        "To suppress this deprecation warning, define `STDEXEC_DISABLE_R5_DEPRECATIONS`.")]]
-#else
-#define STDEXEC_R5_SENDER_DEPRECATION_WARNING
-#define STDEXEC_R5_RECEIVER_DEPRECATION_WARNING
-#define STDEXEC_R5_DEPENDENT_COMPLETION_SIGNATURES_DEPRECATION_WARNING
-#define STDEXEC_R5_NO_ENV_DEPRECATION_WARNING
-#endif
-
-#define STDEXEC_LEGACY_R5_CONCEPTS() 1
-
 STDEXEC_PRAGMA_PUSH()
-STDEXEC_PRAGMA_IGNORE("-Wundefined-inline")
-STDEXEC_PRAGMA_IGNORE("-Wundefined-internal")
+STDEXEC_PRAGMA_IGNORE_GNU("-Wpragmas")
+STDEXEC_PRAGMA_IGNORE_GNU("-Wunknown-warning-option")
+STDEXEC_PRAGMA_IGNORE_GNU("-Wundefined-inline")
+STDEXEC_PRAGMA_IGNORE_GNU("-Wsubobject-linkage")
+
+STDEXEC_PRAGMA_IGNORE_EDG(1302)
+STDEXEC_PRAGMA_IGNORE_EDG(497)
+STDEXEC_PRAGMA_IGNORE_EDG(type_qualifiers_ignored_on_reference)
 
 namespace stdexec
 {
@@ -98,6 +61,152 @@
     static inline constexpr Tag (*signature)(Sig) = nullptr;
 };
 
+struct default_domain;
+struct dependent_domain;
+
+template <class _Sender>
+using tag_of_t = __tag_of<_Sender>;
+
+namespace __domain
+{
+template <class _Tag>
+using __legacy_c11n_for = typename _Tag::__legacy_customizations_t;
+
+template <class _Tag, class... _Args>
+using __legacy_c11n_fn = //
+    __make_dispatcher<__legacy_c11n_for<_Tag>, __none_such, _Args...>;
+
+template <class _Tag, class... _Args>
+concept __has_legacy_c11n = //
+    __callable<__legacy_c11n_fn<_Tag, _Args...>, _Args...>;
+
+struct __legacy_customization
+{
+    template <class _Tag, class _Data, class... _Children>
+        requires __has_legacy_c11n<_Tag, _Data, _Children...>
+    decltype(auto) operator()(_Tag, _Data && __data,
+                              _Children&&... __children) const
+    {
+        return __legacy_c11n_fn<_Tag, _Data, _Children...>()(
+            static_cast<_Data&&>(__data),
+            static_cast<_Children&&>(__children)...);
+    }
+};
+
+template <class _DomainOrTag, class _Sender, class... _Env>
+concept __has_transform_sender =
+    requires(_DomainOrTag __tag, _Sender&& __sender, const _Env&... __env) {
+        __tag.transform_sender((_Sender&&)__sender, __env...);
+    };
+
+template <class _Sender, class... _Env>
+concept __has_default_transform_sender = //
+    sender_expr<_Sender>                 //
+    && __has_transform_sender<tag_of_t<_Sender>, _Sender, _Env...>;
+
+template <class _Type, class _Sender, class _Env>
+concept __has_transform_env =
+    requires(_Type __obj, _Sender&& __sender, _Env&& __env) {
+        __obj.transform_env((_Sender&&)__sender, (_Env&&)__env);
+    };
+
+template <class _Sender, class _Env>
+concept __has_default_transform_env = //
+    sender_expr<_Sender>              //
+    && __has_transform_env<tag_of_t<_Sender>, _Sender, _Env>;
+
+template <class _DomainOrTag, class... _Args>
+concept __has_apply_sender = requires(_DomainOrTag __tag, _Args&&... __args) {
+                                 __tag.apply_sender((_Args&&)__args...);
+                             };
+} // namespace __domain
+
+namespace __write_
+{
+struct __write_t;
+}
+
+struct default_domain
+{
+    default_domain() = default;
+
+    // Called without the environment during eager customization
+    template <class _Sender>
+    STDEXEC_ATTRIBUTE((always_inline))
+    decltype(auto) transform_sender(_Sender&& __sndr) const
+    {
+        // Look for a legacy customization for the given tag, and if found,
+        // apply it.
+        if constexpr (__callable<__sexpr_apply_t, _Sender,
+                                 __domain::__legacy_customization>)
+        {
+            return stdexec::__sexpr_apply((_Sender&&)__sndr,
+                                          __domain::__legacy_customization());
+        }
+        else if constexpr (__domain::__has_default_transform_sender<_Sender>)
+        {
+            return tag_of_t<_Sender>().transform_sender((_Sender&&)__sndr);
+        }
+        else
+        {
+            return static_cast<_Sender>((_Sender&&)__sndr);
+        }
+        STDEXEC_UNREACHABLE();
+    }
+
+    // Called with an environment during lazy customization
+    template <class _Sender, class _Env>
+    STDEXEC_ATTRIBUTE((always_inline))
+    decltype(auto) transform_sender(_Sender&& __sndr, const _Env& __env) const
+    {
+        if constexpr (__domain::__has_default_transform_sender<_Sender, _Env>)
+        {
+            return tag_of_t<_Sender>().transform_sender((_Sender&&)__sndr,
+                                                        __env);
+        }
+        else
+        {
+            return static_cast<_Sender>((_Sender&&)__sndr);
+        }
+        STDEXEC_UNREACHABLE();
+    }
+
+    template <class _Tag, class _Sender, class... _Args>
+        requires __domain::__has_legacy_c11n<_Tag, _Sender, _Args...> ||
+                 __domain::__has_apply_sender<_Tag, _Sender, _Args...>
+    STDEXEC_ATTRIBUTE((always_inline)) decltype(auto)
+        apply_sender(_Tag, _Sender&& __sndr, _Args&&... __args) const
+    {
+        // Look for a legacy customization for the given tag, and if found,
+        // apply it.
+        if constexpr (__domain::__has_legacy_c11n<_Tag, _Sender, _Args...>)
+        {
+            return __domain::__legacy_c11n_fn<_Tag, _Sender, _Args...>()(
+                static_cast<_Sender&&>(__sndr),
+                static_cast<_Args&&>(__args)...);
+        }
+        else
+        {
+            return _Tag().apply_sender((_Sender&&)__sndr, (_Args&&)__args...);
+        }
+        STDEXEC_UNREACHABLE();
+    }
+
+    template <class _Sender, class _Env>
+    decltype(auto) transform_env(_Sender&& __sndr, _Env&& __env) const noexcept
+    {
+        if constexpr (__domain::__has_default_transform_env<_Sender, _Env>)
+        {
+            return tag_of_t<_Sender>().transform_env((_Sender&&)__sndr,
+                                                     (_Env&&)__env);
+        }
+        else
+        {
+            return static_cast<_Env>((_Env&&)__env);
+        }
+    }
+};
+
 //////////////////////////////////////////////////////////////////////////////////////////////////
 // [exec.queries]
 namespace __queries
@@ -122,6 +231,26 @@
     }
 };
 
+struct query_or_t
+{
+    template <class _Query, class _Queryable, class _Default>
+    constexpr auto operator()(_Query, _Queryable&&, _Default&& __default) const
+        noexcept(__nothrow_constructible_from<_Default, _Default&&>) -> _Default
+    {
+        return (_Default&&)__default;
+    }
+
+    template <class _Query, class _Queryable, class _Default>
+        requires __callable<_Query, _Queryable>
+    constexpr auto operator()(_Query __query, _Queryable&& __queryable,
+                              _Default&&) const
+        noexcept(__nothrow_callable<_Query, _Queryable>)
+            -> __call_result_t<_Query, _Queryable>
+    {
+        return ((_Query&&)__query)((_Queryable&&)__queryable);
+    }
+};
+
 struct execute_may_block_caller_t : __query<execute_may_block_caller_t>
 {
     template <class _Tp>
@@ -190,7 +319,7 @@
 
 // TODO: implement allocator concept
 template <class _T0>
-concept __allocator = true;
+concept __allocator_c = true;
 
 struct get_scheduler_t : __query<get_scheduler_t>
 {
@@ -239,7 +368,7 @@
     {
         static_assert(nothrow_tag_invocable<get_allocator_t, const _Env&>);
         static_assert(
-            __allocator<tag_invoke_result_t<get_allocator_t, const _Env&>>);
+            __allocator_c<tag_invoke_result_t<get_allocator_t, const _Env&>>);
         return tag_invoke(get_allocator_t{}, __env);
     }
 
@@ -294,6 +423,26 @@
         -> tag_invoke_result_t<get_completion_scheduler_t<_CPO>,
                                const _Queryable&>;
 };
+
+struct get_domain_t
+{
+    template <class _Ty>
+        requires tag_invocable<get_domain_t, const _Ty&>
+    constexpr auto operator()(const _Ty& __ty) const noexcept
+        -> tag_invoke_result_t<get_domain_t, const _Ty&>
+    {
+        static_assert(nothrow_tag_invocable<get_domain_t, const _Ty&>,
+                      "Customizations of get_domain must be noexcept.");
+        static_assert(__class<tag_invoke_result_t<get_domain_t, const _Ty&>>,
+                      "Customizations of get_domain must return a class type.");
+        return tag_invoke(get_domain_t{}, __ty);
+    }
+
+    friend constexpr bool tag_invoke(forwarding_query_t, get_domain_t) noexcept
+    {
+        return true;
+    }
+};
 } // namespace __queries
 
 using __queries::__has_algorithm_customizations_t;
@@ -302,11 +451,14 @@
 using __queries::get_allocator_t;
 using __queries::get_completion_scheduler_t;
 using __queries::get_delegatee_scheduler_t;
+using __queries::get_domain_t;
 using __queries::get_forward_progress_guarantee_t;
 using __queries::get_scheduler_t;
 using __queries::get_stop_token_t;
+using __queries::query_or_t;
 
 inline constexpr forwarding_query_t forwarding_query{};
+inline constexpr query_or_t query_or{}; // NOT TO SPEC
 inline constexpr execute_may_block_caller_t execute_may_block_caller{};
 inline constexpr __has_algorithm_customizations_t
     __has_algorithm_customizations{};
@@ -316,7 +468,7 @@
 inline constexpr get_delegatee_scheduler_t get_delegatee_scheduler{};
 inline constexpr get_allocator_t get_allocator{};
 inline constexpr get_stop_token_t get_stop_token{};
-#if !STDEXEC_GCC() || defined(__OPTIMIZE__)
+#if !STDEXEC_GCC() || defined(__OPTIMIZE_SIZE__)
 template <__completion_tag _CPO>
 inline constexpr get_completion_scheduler_t<_CPO> get_completion_scheduler{};
 #else
@@ -334,34 +486,74 @@
 template <class _Tag>
 concept __forwarding_query = forwarding_query(_Tag{});
 
+inline constexpr get_domain_t get_domain{};
+
+template <class _Tag, class _Queryable, class _Default>
+using __query_result_or_t =
+    __call_result_t<query_or_t, _Tag, _Queryable, _Default>;
+
 /////////////////////////////////////////////////////////////////////////////
 // env_of
 namespace __env
 {
-struct no_env
-{
-    using __t = no_env;
-    using __id = no_env;
-    template <class _Tag, same_as<no_env> _Self, class... _Ts>
-    friend void tag_invoke(_Tag, _Self, _Ts&&...) = delete;
-};
-
 struct empty_env
 {
     using __t = empty_env;
     using __id = empty_env;
 };
 
-template <class _Tag>
-struct __deleted
-{};
+template <class _Descriptor>
+struct __prop;
+
+template <class _Value, class... _Tags>
+struct __prop<_Value(_Tags...)>
+{
+    using __t = __prop;
+    using __id = __prop;
+    _Value __value_;
+
+    template <__one_of<_Tags...> _Key>
+    friend auto tag_invoke(_Key, const __prop& __self) //
+        noexcept(__nothrow_decay_copyable<_Value>) -> _Value
+    {
+        return __self.__value_;
+    }
+};
+
+template <class... _Tags>
+struct __prop<void(_Tags...)>
+{
+    using __t = __prop;
+    using __id = __prop;
+
+    template <__one_of<_Tags...> _Key, class _Self>
+        requires(std::is_base_of_v<__prop, __decay_t<_Self>>)
+    friend auto tag_invoke(_Key, _Self&&) noexcept = delete;
+};
+
+struct __mkprop_t
+{
+    template <class _Value, class _Tag, class... _Tags>
+    auto operator()(_Value&& __value, _Tag, _Tags...) const
+        noexcept(__nothrow_decay_copyable<_Value>)
+            -> __prop<__decay_t<_Value>(_Tag, _Tags...)>
+    {
+        return {(_Value&&)__value};
+    }
+
+    template <class _Tag>
+    auto operator()(_Tag) const -> __prop<void(_Tag)>
+    {
+        return {};
+    }
+};
 
 template <__nothrow_move_constructible _Fun>
 struct __env_fn
 {
     using __t = __env_fn;
     using __id = __env_fn;
-    STDEXEC_NO_UNIQUE_ADDRESS _Fun __fun_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Fun __fun_;
 
     template <class _Tag>
         requires __callable<const _Fun&, _Tag>
@@ -376,12 +568,13 @@
 template <class _Fun>
 __env_fn(_Fun) -> __env_fn<_Fun>;
 
-template <__nothrow_move_constructible _Env>
+template <class _Env>
 struct __env_fwd
 {
+    static_assert(__nothrow_move_constructible<_Env>);
     using __t = __env_fwd;
     using __id = __env_fwd;
-    STDEXEC_NO_UNIQUE_ADDRESS _Env __env_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Env __env_;
 
     template <__forwarding_query _Tag>
         requires tag_invocable<_Tag, const _Env&>
@@ -393,13 +586,16 @@
     }
 };
 
-template <__nothrow_move_constructible _Env,
-          __nothrow_move_constructible _Base = empty_env>
-struct __env_join : __env_fwd<_Base>
+template <class _Env>
+__env_fwd(_Env&&) -> __env_fwd<_Env>;
+
+template <class _Env, class _Base = empty_env>
+struct __joined_env : __env_fwd<_Base>
 {
-    using __t = __env_join;
-    using __id = __env_join;
-    STDEXEC_NO_UNIQUE_ADDRESS _Env __env_;
+    static_assert(__nothrow_move_constructible<_Env>);
+    using __t = __joined_env;
+    using __id = __joined_env;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Env __env_;
 
     const _Base& base() const noexcept
     {
@@ -408,7 +604,7 @@
 
     template <class _Tag>
         requires tag_invocable<_Tag, const _Env&>
-    friend auto tag_invoke(_Tag, const __env_join& __self) //
+    friend auto tag_invoke(_Tag, const __joined_env& __self) //
         noexcept(nothrow_tag_invocable<_Tag, const _Env&>)
             -> tag_invoke_result_t<_Tag, const _Env&>
     {
@@ -417,67 +613,56 @@
 };
 
 template <class _Tag, class _Base>
-struct __env_join<__env_fn<__deleted<_Tag>>, _Base> : __env_fwd<_Base>
+struct __joined_env<__prop<void(_Tag)>, _Base> : __env_fwd<_Base>
 {
-    using __t = __env_join;
-    using __id = __env_join;
-    STDEXEC_NO_UNIQUE_ADDRESS __env_fn<__deleted<_Tag>> __env_;
+    using __t = __joined_env;
+    using __id = __joined_env;
+    STDEXEC_ATTRIBUTE((no_unique_address)) __prop<void(_Tag)> __env_;
 
-    friend void tag_invoke(_Tag, const __env_join&) noexcept = delete;
+    friend void tag_invoke(_Tag, const __joined_env&) noexcept = delete;
 };
 
-template <class _Env>
-_Env __join_env(_Env&& __env) noexcept
+struct __join_env_t
 {
-    return (_Env&&)__env;
-}
+    template <class _Env>
+    _Env operator()(_Env&& __env) const noexcept
+    {
+        return (_Env&&)__env;
+    }
 
-template <class _Env, class _Base>
-__env_join<_Env, _Base> __join_env(_Env&& __env, _Base&& __base) noexcept
-{
-    static_assert(!same_as<__decay_t<_Env>, no_env>);
-    return {{{(_Base&&)__base}}, (_Env&&)__env};
-}
+    template <class _Env, class _Base>
+    decltype(auto) operator()(_Env && __env, _Base && __base) const noexcept
+    {
+        using __env_t = __decay_t<_Env>;
+        using __base_t = __decay_t<_Base>;
+        if constexpr (__same_as<__env_t, empty_env>)
+        {
+            return _Base((_Base&&)__base);
+        }
+        else if constexpr (__same_as<__base_t, empty_env>)
+        {
+            return _Env((_Env&&)__env);
+        }
+        else
+        {
+            return __joined_env<_Env, _Base>{{(_Base&&)__base}, (_Env&&)__env};
+        }
+    }
 
-template <class _Base>
-_Base __join_env(empty_env, _Base&& __base) noexcept
-{
-    return (_Base&&)__base;
-}
-
-template <class _Env>
-_Env __join_env(_Env&& __env, empty_env) noexcept
-{
-    static_assert(!same_as<__decay_t<_Env>, no_env>);
-    return (_Env&&)__env;
-}
-
-inline empty_env __join_env(empty_env, empty_env) noexcept
-{
-    return {};
-}
-
-template <class _Env>
-no_env __join_env(_Env&&, no_env) noexcept
-    requires true
-{
-    static_assert(!same_as<__decay_t<_Env>, no_env>);
-    return {};
-}
-
-template <class _Env0, class _Env1, class _Env2, class... _Envs>
-auto __join_env(_Env0&& __env0, _Env1&& __env1, _Env2&& __env2,
-                _Envs&&... __envs) noexcept
-{
-    return __env::__join_env(
-        (_Env0&&)__env0,
-        __env::__join_env(
-            (_Env1&&)__env1,
-            __env::__join_env((_Env2&&)__env2, (_Envs&&)__envs...)));
-}
+    template <class _Env0, class _Env1, class _Env2, class... _Envs>
+    decltype(auto) operator()(_Env0 && __env0, _Env1 && __env1, _Env2 && __env2,
+                              _Envs&&... __envs) const noexcept
+    {
+        const auto& __join_env = *this;
+        return __join_env(
+            (_Env0&&)__env0,
+            __join_env((_Env1&&)__env1,
+                       __join_env((_Env2&&)__env2, (_Envs&&)__envs...)));
+    }
+};
 
 template <class... _Envs>
-using __env_join_t = decltype(__env::__join_env(__declval<_Envs>()...));
+using __env_join_t = __call_result_t<__join_env_t, _Envs...>;
 
 // To be kept in sync with the promise type used in __connect_awaitable
 template <class _Env>
@@ -502,23 +687,6 @@
         -> const _Env&;
 };
 
-template <class _Tag, __nothrow_move_constructible _Value>
-constexpr auto __with_(_Tag, _Value __val) noexcept
-{
-    return __env_fn{
-        [__val = std::move(__val)](_Tag) noexcept(
-            __nothrow_copy_constructible<_Value>) { return __val; }};
-}
-
-template <class _Tag>
-__env_fn<__deleted<_Tag>> __with_(_Tag) noexcept
-{
-    return {};
-}
-
-template <class... _Ts>
-using __with = decltype(__env::__with_(__declval<_Ts>()...));
-
 // For making an environment from key/value pairs and optionally
 // another environment.
 struct __make_env_t
@@ -528,7 +696,7 @@
     auto operator()(_Base&& __base, _Env&& __env) const noexcept
         -> __env_join_t<_Env, _Base>
     {
-        return stdexec::__env::__join_env((_Env&&)__env, (_Base&&)__base);
+        return __join_env_t()((_Env&&)__env, (_Base&&)__base);
     }
 
     template <__nothrow_move_constructible _Env>
@@ -543,7 +711,9 @@
 {
     template <class _EnvProvider>
         requires tag_invocable<get_env_t, const _EnvProvider&>
-    constexpr auto operator()(const _EnvProvider& __with_env) const noexcept
+    STDEXEC_ATTRIBUTE((always_inline)) //
+        constexpr auto
+        operator()(const _EnvProvider& __with_env) const noexcept
         -> tag_invoke_result_t<get_env_t, const _EnvProvider&>
     {
         static_assert(
@@ -552,48 +722,34 @@
         return tag_invoke(*this, __with_env);
     }
 
-    // NOT TO SPEC: The overload below checks the non-standard
-    // enable_sender to determine whether to provide backwards
-    // compatible behavior for R5 version sender types. When we
-    // deprecate R5 support, we can bring this overload in line with
-    // P2300R7.
     template <class _EnvProvider>
-    constexpr decltype(auto)
-        operator()(const _EnvProvider & __with_env) const noexcept
+    constexpr empty_env operator()(const _EnvProvider&) const noexcept
     {
-        if constexpr (!enable_sender<_EnvProvider>)
-        {
-            return __with_env;
-        }
-        else
-        {
-            return empty_env{};
-        }
+        return {};
     }
 };
 } // namespace __env
 
 using __env::empty_env;
-using __env::no_env;
 using __empty_env
     [[deprecated("Please use stdexec::empty_env now.")]] = empty_env;
 
 using __env::__env_promise;
-using __env::__with;
-using __env::__with_;
-using no_env_promise = __env_promise<no_env>;
 
 inline constexpr __env::__make_env_t __make_env{};
+inline constexpr __env::__join_env_t __join_env{};
 inline constexpr __env::get_env_t get_env{};
 
-template <class... _Ts>
-using __make_env_t = decltype(__make_env(__declval<_Ts>()...));
+// for making an environment from a single key/value pair
+inline constexpr __env::__mkprop_t __mkprop{};
 
-#if STDEXEC_LEGACY_R5_CONCEPTS()
-using __default_env = no_env;
-#else
+template <class _Tag, class _Value = void>
+using __with = __env::__prop<_Value(_Tag)>;
+
+template <class... _Ts>
+using __make_env_t = __call_result_t<__env::__make_env_t, _Ts...>;
+
 using __default_env = empty_env;
-#endif
 
 template <class _EnvProvider>
 concept environment_provider = //
@@ -601,14 +757,195 @@
         {
             get_env(std::as_const(__ep))
         } -> queryable;
-        // NOT TO SPEC: Remove the following line when we deprecate all
-        // R5 entities.
-        {
-            get_env(std::as_const(__ep))
-        } -> __none_of<no_env, void>;
     };
 
 /////////////////////////////////////////////////////////////////////////////
+template <class _Sender, class _Scheduler, class _Tag = set_value_t>
+concept __completes_on = __decays_to<
+    __call_result_t<get_completion_scheduler_t<_Tag>, env_of_t<_Sender>>,
+    _Scheduler>;
+
+/////////////////////////////////////////////////////////////////////////////
+template <class _Sender, class _Scheduler, class _Env>
+concept __starts_on =
+    __decays_to<__call_result_t<get_scheduler_t, _Env>, _Scheduler>;
+
+/////////////////////////////////////////////////////////////////////////////
+namespace __detail
+{
+template <class _Env, class _Tag>
+using __completion_scheduler_for =
+    __meval_or<__call_result_t, __none_such, get_completion_scheduler_t<_Tag>,
+               _Env>;
+
+template <class _Env, class _Tag>
+using __completion_domain_for =
+    __meval_or<__call_result_t, __none_such, get_domain_t,
+               __completion_scheduler_for<_Env, _Tag>>;
+
+// Check the value, error, and stopped channels for completion schedulers.
+// Of the completion schedulers that are known, they must all have compatible
+// domains. This computes that domain, or else returns __none_such if there
+// are no completion schedulers or if they don't specify a domain.
+template <class _Env>
+struct __completion_domain_or_none_ :
+    __mdefer_<__transform<
+                  __mbind_front_q<__completion_domain_for, _Env>,
+                  __remove<__none_such, __munique<__msingle_or<__none_such>>>>,
+              set_value_t, set_error_t, set_stopped_t>
+{};
+
+template <class _Sender>
+using __completion_domain_or_none =
+    __t<__completion_domain_or_none_<env_of_t<_Sender>>>;
+
+template <class _Sender>
+concept __consistent_completion_domains =
+    __mvalid<__completion_domain_or_none, _Sender>;
+
+template <class _Sender>
+concept __has_completion_domain =
+    (!same_as<__completion_domain_or_none<_Sender>, __none_such>);
+
+template <__has_completion_domain _Sender>
+using __completion_domain_of = __completion_domain_or_none<_Sender>;
+} // namespace __detail
+
+/////////////////////////////////////////////////////////////////////////////
+inline constexpr struct __get_early_domain_t
+{
+    template <class _Sender, class _Default = default_domain>
+    auto operator()(const _Sender&, _Default __def = {}) const noexcept
+    {
+        if constexpr (__callable<get_domain_t, env_of_t<_Sender>>)
+        {
+            return __call_result_t<get_domain_t, env_of_t<_Sender>>();
+        }
+        else if constexpr (__detail::__has_completion_domain<_Sender>)
+        {
+            return __detail::__completion_domain_of<_Sender>();
+        }
+        else
+        {
+            return __def;
+        }
+        STDEXEC_UNREACHABLE();
+    }
+} __get_early_domain{};
+
+template <class _Sender, class _Default = default_domain>
+using __early_domain_of_t =
+    __call_result_t<__get_early_domain_t, _Sender, _Default>;
+
+/////////////////////////////////////////////////////////////////////////////
+inline constexpr struct __get_late_domain_t
+{
+    // When connect is looking for a customization, it first checks the sender's
+    // domain. If the sender knows the domain in which it completes, then that
+    // is where the subsequent task will execute. Otherwise, look to the
+    // receiver for late-bound information about the current execution context.
+    template <class _Sender, class _Env>
+    auto operator()(const _Sender& __sndr, const _Env& __env) const noexcept
+    {
+        if constexpr (!same_as<dependent_domain,
+                               __early_domain_of_t<_Sender, dependent_domain>>)
+        {
+            return __get_early_domain(__sndr);
+        }
+        else if constexpr (__callable<get_domain_t, const _Env&>)
+        {
+            return get_domain(__env);
+        }
+        else if constexpr (__callable<__composed<get_domain_t, get_scheduler_t>,
+                                      const _Env&>)
+        {
+            return get_domain(get_scheduler(__env));
+        }
+        else
+        {
+            return default_domain();
+        }
+        STDEXEC_UNREACHABLE();
+    }
+
+    // The transfer algorithm is the exception to the rule. It ignores the
+    // domain of the predecessor, and dispatches based on the domain of the
+    // scheduler to which execution is being transferred.
+    template <sender_expr_for<transfer_t> _Sender, class _Env>
+    auto operator()(const _Sender& __sndr, const _Env&) const noexcept
+    {
+        return __sexpr_apply(__sndr,
+                             [](__ignore, auto& __data, __ignore) noexcept {
+            auto __sched = get_completion_scheduler<set_value_t>(__data);
+            return query_or(get_domain, __sched, default_domain());
+        });
+    }
+} __get_late_domain{};
+
+template <class _Sender, class _Env>
+using __late_domain_of_t = __call_result_t<__get_late_domain_t, _Sender, _Env>;
+
+namespace __domain
+{
+struct __common_domain_fn
+{
+    static default_domain __common_domain() noexcept
+    {
+        return {};
+    }
+
+    template <class _Domain, class... _OtherDomains>
+        requires __all_of<_Domain, _OtherDomains...>
+    static _Domain __common_domain(_Domain __domain, _OtherDomains...) noexcept
+    {
+        return (_Domain&&)__domain;
+    }
+
+    template <class... _Domains>
+    static auto __common_domain(_Domains...) noexcept //
+        -> __if_c<__one_of<dependent_domain, _Domains...>, dependent_domain,
+                  __none_such>
+    {
+        return {};
+    }
+
+    auto operator()(__ignore, __ignore, const auto&... __sndrs) const noexcept
+    {
+        return __common_domain(__get_early_domain(__sndrs)...);
+    }
+};
+
+template <class... _Senders>
+using __common_domain_t = //
+    __call_result_t<__common_domain_fn, int, int, _Senders...>;
+
+template <class... _Senders>
+concept __has_common_domain = //
+    __none_of<__none_such, __common_domain_t<_Senders...>>;
+
+template <class _Tag>
+struct __get_env_common_domain
+{
+    template <sender_expr_for<_Tag> _Self>
+    static auto get_env(const _Self& __self) noexcept
+    {
+        using _Domain =
+            __call_result_t<__sexpr_apply_t, const _Self&, __common_domain_fn>;
+        if constexpr (same_as<_Domain, default_domain>)
+        {
+            return empty_env();
+        }
+        else
+        {
+            return __mkprop(__sexpr_apply(__self, __common_domain_fn()),
+                            get_domain);
+        }
+        STDEXEC_UNREACHABLE();
+    }
+};
+} // namespace __domain
+
+/////////////////////////////////////////////////////////////////////////////
 // [execution.receivers]
 namespace __receivers
 {
@@ -619,7 +956,7 @@
 
     template <class _Receiver, class... _As>
         requires tag_invocable<set_value_t, _Receiver, _As...>
-    STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
+    STDEXEC_ATTRIBUTE((host, device, always_inline)) //
         void
         operator()(_Receiver&& __rcvr, _As&&... __as) const noexcept
     {
@@ -636,7 +973,7 @@
 
     template <class _Receiver, class _Error>
         requires tag_invocable<set_error_t, _Receiver, _Error>
-    STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
+    STDEXEC_ATTRIBUTE((host, device, always_inline)) //
         void
         operator()(_Receiver&& __rcvr, _Error&& __err) const noexcept
     {
@@ -653,7 +990,7 @@
 
     template <class _Receiver>
         requires tag_invocable<set_stopped_t, _Receiver>
-    STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
+    STDEXEC_ATTRIBUTE((host, device, always_inline)) //
         void
         operator()(_Receiver&& __rcvr) const noexcept
     {
@@ -695,6 +1032,46 @@
     }
 } __try_call{};
 
+namespace __error__
+{
+inline constexpr __mstring __unrecognized_sender_type_diagnostic =
+    "The given type cannot be used as a sender with the given environment "
+    "because the attempt to compute the completion signatures failed."__csz;
+
+template <__mstring _Diagnostic = __unrecognized_sender_type_diagnostic>
+struct _UNRECOGNIZED_SENDER_TYPE_;
+
+template <class _Sender>
+struct _WITH_SENDER_;
+
+template <class... _Senders>
+struct _WITH_SENDERS_;
+
+template <class _Env>
+struct _WITH_ENVIRONMENT_;
+
+template <class _Ty>
+struct _WITH_TYPE_;
+
+template <class _Receiver>
+struct _WITH_RECEIVER_;
+
+template <class _Sig>
+struct _MISSING_COMPLETION_SIGNAL_;
+} // namespace __error__
+
+using __error__::_MISSING_COMPLETION_SIGNAL_;
+using __error__::_UNRECOGNIZED_SENDER_TYPE_;
+using __error__::_WITH_ENVIRONMENT_;
+using __error__::_WITH_RECEIVER_;
+using __error__::_WITH_TYPE_;
+
+template <class _Sender>
+using _WITH_SENDER_ = __error__::_WITH_SENDER_<__name_of<_Sender>>;
+
+template <class... _Senders>
+using _WITH_SENDERS_ = __error__::_WITH_SENDERS_<__name_of<_Senders>...>;
+
 /////////////////////////////////////////////////////////////////////////////
 // completion_signatures
 namespace __compl_sigs
@@ -734,17 +1111,6 @@
 void __test(_Tag (*)(_Args...) noexcept) = delete;
 #endif
 
-// BUGBUG not to spec!
-struct __dependent
-{
-#if !STDEXEC_STD_NO_COROUTINES_
-    bool await_ready();
-    template <class _Env>
-    void await_suspend(__coro::coroutine_handle<__env_promise<_Env>>);
-    __dependent await_resume();
-#endif
-};
-
 #if STDEXEC_NVHPC()
 template <class _Sig>
 concept __completion_signature = __compl_sigs::__is_compl_sig<_Sig>;
@@ -765,9 +1131,6 @@
 
 using __compl_sigs::__completion_signature;
 
-template <same_as<no_env>>
-using dependent_completion_signatures = __compl_sigs::__dependent;
-
 template <__compl_sigs::__completion_signature... _Sigs>
 struct completion_signatures
 {
@@ -803,22 +1166,33 @@
     __meval<__for_all_sigs, _Completions, _TaggedTuple, _Variant>;
 } // namespace __compl_sigs
 
-template <class _Ty>
-concept __is_completion_signatures =
-    __is_instance_of<_Ty, completion_signatures>;
+template <class _Completions>
+concept __valid_completion_signatures = //
+    __is_instance_of<_Completions, completion_signatures>;
 
-template <class...>
-auto __concat_completion_signatures_impl() //
-    -> dependent_completion_signatures<no_env>;
+template <class _Completions>
+using __invalid_completion_signatures_t = //
+    __mbool<!__valid_completion_signatures<_Completions>>;
 
-template <__is_completion_signatures... _Completions>
-auto __concat_completion_signatures_impl()
-    -> __minvoke<__mconcat<__munique<__q<completion_signatures>>>,
-                 _Completions...>;
+template <__mstring _Msg =
+              "Expected an instance of template completion_signatures<>"__csz>
+struct _INVALID_COMPLETION_SIGNATURES_TYPE_
+{
+    template <class... _Completions>
+    using __f = //
+        __mexception<
+            _INVALID_COMPLETION_SIGNATURES_TYPE_<>,
+            __minvoke<__mfind_if<__q<__invalid_completion_signatures_t>,
+                                 __mcompose<__q<_WITH_TYPE_>, __q<__mfront>>>,
+                      _Completions...>>;
+};
 
 template <class... _Completions>
 using __concat_completion_signatures_impl_t = //
-    decltype(__concat_completion_signatures_impl<_Completions...>());
+    __minvoke<__if_c<(__valid_completion_signatures<_Completions> && ...),
+                     __mconcat<__munique<__q<completion_signatures>>>,
+                     _INVALID_COMPLETION_SIGNATURES_TYPE_<>>,
+              _Completions...>;
 
 template <class... _Completions>
 struct __concat_completion_signatures_
@@ -830,32 +1204,8 @@
 using __concat_completion_signatures_t =
     __t<__concat_completion_signatures_<_Completions...>>;
 
-template <class _Completions, class _Env>
-inline constexpr bool __expecting_completion_signatures = false;
-
-template <class... _Sigs, class _Env>
-inline constexpr bool
-    __expecting_completion_signatures<completion_signatures<_Sigs...>, _Env> =
-        true;
-
-template <>
-inline constexpr bool __expecting_completion_signatures<
-    dependent_completion_signatures<no_env>, no_env> = true;
-
-template <class _Completions, class _Env>
-concept __valid_completion_signatures =
-    __expecting_completion_signatures<_Completions, _Env>;
-
 /////////////////////////////////////////////////////////////////////////////
 // [execution.receivers]
-template <class _Receiver>
-struct _WITH_RECEIVER_
-{};
-
-template <class _Sig>
-struct _MISSING_COMPLETION_SIGNAL_
-{};
-
 template <class _Receiver, class _Tag, class... _Args>
 auto __try_completion(_Tag (*)(_Args...))
     -> __mexception<_MISSING_COMPLETION_SIGNAL_<_Tag(_Args...)>,
@@ -870,6 +1220,15 @@
     -> decltype((__msuccess(), ...,
                  stdexec::__try_completion<_Receiver>((_Sigs*)nullptr)));
 
+template <class _Sender, class _Env>
+using __unrecognized_sender_error = //
+    __mexception<_UNRECOGNIZED_SENDER_TYPE_<>, _WITH_SENDER_<_Sender>,
+                 _WITH_ENVIRONMENT_<_Env>>;
+
+template <class _Sender, class _Env>
+using __completion_signatures_of_t =
+    __call_result_t<get_completion_signatures_t, _Sender, _Env>;
+
 /////////////////////////////////////////////////////////////////////////////
 // [execution.receivers]
 struct __receiver_base
@@ -884,25 +1243,8 @@
 inline constexpr bool enable_receiver =
     __enable_receiver<_Receiver>; // NOT TO SPEC
 
-//   NOT TO SPEC:
-//   As we upgrade the receiver related entities from R5 to R7,
-//   we allow types that do not yet satisfy enable_receiver to
-//   still satisfy the receiver concept if the type provides an
-//   explicit get_env. All R5 receivers provided an explicit get_env,
-//   so this is backwards compatible.
 template <class _Receiver>
-concept __receiver_r5_or_r7 =  //
-    enable_receiver<_Receiver> //
-    || tag_invocable<get_env_t, _Receiver>;
-
-template <class _Receiver>
-concept __receiver = //
-                     // Nested requirement here is to make this an atomic
-                     // constraint
-    requires { requires __receiver_r5_or_r7<__decay_t<_Receiver>>; };
-
-template <class _Receiver>
-concept receiver = __receiver<_Receiver> &&                     //
+concept receiver = enable_receiver<__decay_t<_Receiver>> &&     //
                    environment_provider<__cref_t<_Receiver>> && //
                    move_constructible<__decay_t<_Receiver>> &&  //
                    constructible_from<__decay_t<_Receiver>, _Receiver>;
@@ -946,6 +1288,24 @@
 struct __completion_signatures
 {};
 
+#if STDEXEC_MSVC()
+// MSVCBUG
+// https://developercommunity.visualstudio.com/t/Explicit-variable-template-specialisatio/10360032
+// MSVCBUG
+// https://developercommunity.visualstudio.com/t/Non-function-type-interpreted-as-functio/10447831
+
+template <class _Sig>
+struct __normalize_sig;
+
+template <class _Tag, class... _Args>
+struct __normalize_sig<_Tag(_Args...)>
+{
+    using __type = _Tag (*)(_Args&&...);
+};
+
+template <class _Sig>
+using __normalize_sig_t = typename __normalize_sig<_Sig>::__type;
+#else
 template <class _Sig>
 extern int __normalize_sig;
 
@@ -954,6 +1314,7 @@
 
 template <class _Sig>
 using __normalize_sig_t = decltype(__normalize_sig<_Sig>);
+#endif
 
 template <class... _Sigs>
 struct __valid_completions
@@ -961,9 +1322,9 @@
     template <derived_from<__valid_completions> _Self, class _Tag,
               class... _Args>
         requires __one_of<_Tag (*)(_Args&&...), _Sigs...>
-    STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
-        friend void
-        tag_invoke(_Tag, _Self&&, _Args&&...) noexcept
+    STDEXEC_ATTRIBUTE((host,
+                       device)) friend void tag_invoke(_Tag, _Self&&,
+                                                       _Args&&...) noexcept
     {
         STDEXEC_TERMINATE();
     }
@@ -987,9 +1348,8 @@
     using is_receiver = void;
 
     template <same_as<get_env_t> _Tag>
-    STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
-        friend __debug_env_t<_Env>
-        tag_invoke(_Tag, __debug_receiver) noexcept
+    STDEXEC_ATTRIBUTE((host, device))
+    friend __debug_env_t<_Env> tag_invoke(_Tag, __debug_receiver) noexcept
     {
         STDEXEC_TERMINATE();
     }
@@ -1014,9 +1374,8 @@
 [[deprecated(
     "The sender claims to send a particular set of completions,"
     " but in actual fact it completes with a result that is not"
-    " one of the declared completion signatures.")]] STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
-    void
-    _ATTENTION_() noexcept
+    " one of the declared completion signatures.")]] STDEXEC_ATTRIBUTE((host,
+                                                                        device)) void _ATTENTION_() noexcept
 {}
 
 template <class _Sig>
@@ -1025,6 +1384,9 @@
     struct __t
     {
         template <class _CvrefSenderId, class _Env, class... _Sigs>
+        // BUGBUG this works around a recently (aug 2023) introduced regression
+        // in nvc++
+            requires(!__one_of<_Sig, _Sigs...>)
         __t(__debug_receiver<_CvrefSenderId, _Env,
                              completion_signatures<_Sigs...>>&&) noexcept
         {
@@ -1034,17 +1396,16 @@
                 _WARNING_< //
                     _COMPLETION_SIGNATURES_MISMATCH_,
                     _COMPLETION_SIGNATURE_<_Sig>, _IS_NOT_ONE_OF_<_Sigs...>,
-                    _SIGNAL_SENT_BY_SENDER_<_Sender>>;
+                    _SIGNAL_SENT_BY_SENDER_<__name_of<_Sender>>>;
             __debug::_ATTENTION_<_What>();
         }
     };
 };
 
 template <__completion_tag _Tag, class... _Args>
-STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
-    void
-    tag_invoke(_Tag, __t<__invalid_completion<_Tag(_Args...)>>,
-               _Args&&...) noexcept
+STDEXEC_ATTRIBUTE((host, device))
+void tag_invoke(_Tag, __t<__invalid_completion<_Tag(_Args...)>>,
+                _Args&&...) noexcept
 {}
 
 struct __debug_operation
@@ -1101,7 +1462,7 @@
 template <class _Sigs, class _Env = empty_env, class _Sender>
 void __debug_sender(_Sender&& __sndr, const _Env& = {})
 {
-    if constexpr (!__is_debug_env<_Env> && !same_as<_Env, no_env>)
+    if constexpr (!__is_debug_env<_Env>)
     {
         if (sizeof(_Sender) == ~0)
         { // never true
@@ -1121,7 +1482,7 @@
 template <class _Env = empty_env, class _Sender>
 void __debug_sender(_Sender&& __sndr, const _Env& = {})
 {
-    if constexpr (!__is_debug_env<_Env> && !same_as<_Env, no_env>)
+    if constexpr (!__is_debug_env<_Env>)
     {
         if (sizeof(_Sender) == ~0)
         { // never true
@@ -1148,76 +1509,263 @@
 using __debug::__is_debug_env;
 
 /////////////////////////////////////////////////////////////////////////////
+// dependent_domain
+struct dependent_domain
+{
+    template <sender_expr _Sender, class _Env>
+        requires same_as<__early_domain_of_t<_Sender>, dependent_domain>
+    STDEXEC_ATTRIBUTE((always_inline)) decltype(auto)
+        transform_sender(_Sender&& __sndr, const _Env& __env) const;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// [execution.transform_sender]
+namespace __domain
+{
+struct __transform_env
+{
+    template <class _Domain, class _Sender, class _Env>
+    STDEXEC_ATTRIBUTE((always_inline))
+    /*constexpr*/ decltype(auto) operator()(_Domain __dom, _Sender && __sndr,
+                                            _Env && __env) const noexcept
+    {
+        if constexpr (__domain::__has_transform_env<_Domain, _Sender, _Env>)
+        {
+            return __dom.transform_env((_Sender&&)__sndr, (_Env&&)__env);
+        }
+        else
+        {
+            return default_domain().transform_env((_Sender&&)__sndr,
+                                                  (_Env&&)__env);
+        }
+    }
+};
+
+struct __transform_sender_1
+{
+    template <class _Domain, class _Sender, class... _Env>
+    STDEXEC_ATTRIBUTE((always_inline))
+    /*constexpr*/ decltype(auto) operator()(_Domain __dom, _Sender && __sndr,
+                                            const _Env&... __env) const
+    {
+        if constexpr (__domain::__has_transform_sender<_Domain, _Sender,
+                                                       _Env...>)
+        {
+            return __dom.transform_sender((_Sender&&)__sndr, __env...);
+        }
+        else
+        {
+            return default_domain().transform_sender((_Sender&&)__sndr,
+                                                     __env...);
+        }
+    }
+};
+
+template <class _Ty, class _Uy>
+concept __decay_same_as = same_as<__decay_t<_Ty>, __decay_t<_Uy>>;
+
+struct __transform_sender
+{
+    template <class _Self = __transform_sender, class _Domain, class _Sender,
+              class... _Env>
+    STDEXEC_ATTRIBUTE((always_inline))
+    /*constexpr*/ decltype(auto) operator()(_Domain __dom, _Sender && __sndr,
+                                            const _Env&... __env) const
+    {
+        using _Sender2 = __call_result_t<__transform_sender_1, _Domain, _Sender,
+                                         const _Env&...>;
+        // If the transformation doesn't change the sender's type, then do not
+        // apply the transform recursively.
+        if constexpr (__decay_same_as<_Sender, _Sender2>)
+        {
+            return __transform_sender_1()(__dom, (_Sender&&)__sndr, __env...);
+        }
+        else
+        {
+            // We transformed the sender and got back a different sender.
+            // Transform that one too.
+            return _Self()(
+                __dom,
+                __transform_sender_1()(__dom, (_Sender&&)__sndr, __env...),
+                __env...);
+        }
+    }
+};
+
+struct __transform_dependent_sender
+{
+    // If we are doing a lazy customization of a type whose domain is
+    // value-dependent (e.g., let_value), first transform the sender to
+    // determine the domain. Then continue transforming the sender with the
+    // requested domain.
+    template <class _Domain, sender_expr _Sender, class _Env>
+        requires same_as<__early_domain_of_t<_Sender>, dependent_domain>
+    /*constexpr*/ decltype(auto) operator()(_Domain __dom, _Sender && __sndr,
+                                            const _Env & __env) const
+    {
+        static_assert(__none_of<_Domain, dependent_domain>);
+        return __transform_sender()(
+            __dom,
+            dependent_domain().transform_sender((_Sender&&)__sndr, __env),
+            __env);
+    }
+};
+} // namespace __domain
+
+/////////////////////////////////////////////////////////////////////////////
+// [execution.transform_sender]
+inline constexpr struct transform_sender_t :
+    __domain::__transform_sender,
+    __domain::__transform_dependent_sender
+{
+    using __domain::__transform_sender::operator();
+    using __domain::__transform_dependent_sender::operator();
+} transform_sender{};
+
+template <class _Domain, class _Sender, class... _Env>
+using transform_sender_result_t =
+    __call_result_t<transform_sender_t, _Domain, _Sender, _Env...>;
+
+inline constexpr __domain::__transform_env transform_env{};
+
+struct _CHILD_SENDERS_WITH_DIFFERENT_DOMAINS_
+{};
+
+template <sender_expr _Sender, class _Env>
+    requires same_as<__early_domain_of_t<_Sender>, dependent_domain>
+decltype(auto) dependent_domain::transform_sender(_Sender&& __sndr,
+                                                  const _Env& __env) const
+{
+    // apply any algorithm-specific transformation to the environment
+    const auto& __env2 = transform_env(*this, (_Sender&&)__sndr, __env);
+
+    // recursively transform the sender to determine the domain
+    return __sexpr_apply((_Sender&&)__sndr,
+                         [&]<class _Tag, class _Data, class... _Childs>(
+                             _Tag, _Data&& __data, _Childs&&... __childs) {
+        // TODO: propagate meta-exceptions here:
+        auto __sndr2 = __make_sexpr<_Tag>(
+            (_Data&&)__data, __domain::__transform_sender()(
+                                 *this, (_Childs&&)__childs, __env2)...);
+        using _Sender2 = decltype(__sndr2);
+
+        auto __domain2 = __sexpr_apply(__sndr2, __domain::__common_domain_fn());
+        using _Domain2 = decltype(__domain2);
+
+        if constexpr (same_as<_Domain2, __none_such>)
+        {
+            return __mexception<_CHILD_SENDERS_WITH_DIFFERENT_DOMAINS_,
+                                _WITH_SENDER_<_Sender2>>();
+        }
+        else
+        {
+            return __domain::__transform_sender()(__domain2, std::move(__sndr2),
+                                                  __env);
+        }
+        STDEXEC_UNREACHABLE();
+    });
+}
+
+// A helper for use when building sender trees where each node must be
+// transformed.
+template <class _Domain, class _Env>
+auto __make_transformer(_Domain, const _Env& __env)
+{
+    return [&]<class _Tag>(_Tag) {
+        return [&]<class... _Args>(_Args&&... __args) -> decltype(auto) {
+            return stdexec::transform_sender(_Domain(),
+                                             _Tag()((_Args&&)__args...), __env);
+        };
+    };
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template <class _Tag, class _Domain, class _Sender, class... _Args>
+concept __has_implementation_for =
+    __domain::__has_apply_sender<_Domain, _Tag, _Sender, _Args...> ||
+    __domain::__has_apply_sender<default_domain, _Tag, _Sender, _Args...>;
+
+/////////////////////////////////////////////////////////////////////////////
+// [execution.apply_sender]
+inline constexpr struct apply_sender_t
+{
+    template <class _Domain, class _Tag, class _Sender, class... _Args>
+        requires __has_implementation_for<_Tag, _Domain, _Sender, _Args...>
+    STDEXEC_ATTRIBUTE((always_inline))
+        /*constexpr*/ decltype(auto)
+            operator()(_Domain __dom, _Tag, _Sender && __sndr,
+                       _Args&&... __args) const
+    {
+        if constexpr (__domain::__has_apply_sender<_Domain, _Tag, _Sender,
+                                                   _Args...>)
+        {
+            return __dom.apply_sender(_Tag(), (_Sender&&)__sndr,
+                                      (_Args&&)__args...);
+        }
+        else
+        {
+            return default_domain().apply_sender(_Tag(), (_Sender&&)__sndr,
+                                                 (_Args&&)__args...);
+        }
+    }
+} apply_sender{};
+
+template <class _Domain, class _Tag, class _Sender, class... _Args>
+using apply_sender_result_t =
+    __call_result_t<apply_sender_t, _Domain, _Tag, _Sender, _Args...>;
+
+/////////////////////////////////////////////////////////////////////////////
 // [execution.sndtraits]
 namespace __get_completion_signatures
 {
 template <class _Sender, class _Env>
-concept __r7_style_sender = same_as<_Env, no_env> &&
-                            enable_sender<__decay_t<_Sender>>;
+using __tfx_sender =
+    transform_sender_result_t<__late_domain_of_t<_Sender, _Env>, _Sender, _Env>;
 
 template <class _Sender, class _Env>
-concept __with_tag_invoke =
-    __valid<tag_invoke_result_t, get_completion_signatures_t, _Sender, _Env>;
+concept __with_tag_invoke = //
+    tag_invocable<get_completion_signatures_t, __tfx_sender<_Sender, _Env>,
+                  _Env>;
 
-template <class _Sender, class...>
-using __member_alias_t = typename __decay_t<_Sender>::completion_signatures;
+template <class _Sender, class _Env>
+using __member_alias_t = //
+    typename __decay_t<__tfx_sender<_Sender, _Env>>::completion_signatures;
 
-template <class _Sender>
-concept __with_member_alias = __valid<__member_alias_t, _Sender>;
+template <class _Sender, class _Env = empty_env>
+concept __with_member_alias = __mvalid<__member_alias_t, _Sender, _Env>;
 
 struct get_completion_signatures_t
 {
     template <class _Sender, class _Env>
     static auto __impl()
     {
-        static_assert(STDEXEC_LEGACY_R5_CONCEPTS() || !same_as<_Env, no_env>);
         static_assert(sizeof(_Sender),
                       "Incomplete type used with get_completion_signatures");
         static_assert(sizeof(_Env),
                       "Incomplete type used with get_completion_signatures");
+
         if constexpr (__with_tag_invoke<_Sender, _Env>)
         {
-            using _Result =
-                tag_invoke_result_t<get_completion_signatures_t, _Sender, _Env>;
-            if constexpr (same_as<_Env, no_env> && __merror<_Result>)
-            {
-                return (dependent_completion_signatures<no_env>(*)()) nullptr;
-            }
-            else
-            {
-                return (_Result(*)()) nullptr;
-            }
+            using _TfxSender = __tfx_sender<_Sender, _Env>;
+            using _Result = tag_invoke_result_t<get_completion_signatures_t,
+                                                _TfxSender, _Env>;
+            return (_Result(*)()) nullptr;
         }
-        else if constexpr (__with_member_alias<_Sender>)
+        else if constexpr (__with_member_alias<_Sender, _Env>)
         {
-            return (__member_alias_t<_Sender, _Env>(*)()) nullptr;
+            using _Result = __member_alias_t<_Sender, _Env>;
+            return (_Result(*)()) nullptr;
         }
         else if constexpr (__awaitable<_Sender, __env_promise<_Env>>)
         {
             using _Result = __await_result_t<_Sender, __env_promise<_Env>>;
-            if constexpr (same_as<_Result,
-                                  dependent_completion_signatures<no_env>>)
-            {
-                return (dependent_completion_signatures<no_env>(*)()) nullptr;
-            }
-            else
-            {
-                return (completion_signatures<
-                        // set_value_t() or set_value_t(T)
-                        __minvoke<__remove<void, __qf<set_value_t>>, _Result>,
-                        set_error_t(std::exception_ptr),
-                        set_stopped_t()>(*)()) nullptr;
-            }
+            return (completion_signatures<
+                    // set_value_t() or set_value_t(T)
+                    __minvoke<__remove<void, __qf<set_value_t>>, _Result>,
+                    set_error_t(std::exception_ptr),
+                    set_stopped_t()>(*)()) nullptr;
         }
-        else
-#if STDEXEC_LEGACY_R5_CONCEPTS()
-            if constexpr (__r7_style_sender<_Sender, _Env>)
-        {
-            return (dependent_completion_signatures<no_env>(*)()) nullptr;
-        }
-        else
-#endif
-            if constexpr (__is_debug_env<_Env>)
+        else if constexpr (__is_debug_env<_Env>)
         {
             using __tag_invoke::tag_invoke;
             // This ought to cause a hard error that indicates where the problem
@@ -1228,18 +1776,16 @@
         }
         else
         {
-            return (void (*)()) nullptr;
+            using _Result =
+                __mexception<_UNRECOGNIZED_SENDER_TYPE_<>,
+                             _WITH_SENDER_<_Sender>, _WITH_ENVIRONMENT_<_Env>>;
+            return (_Result(*)()) nullptr;
         }
     }
 
+    // NOT TO SPEC: if we're unable to compute the completion signatures,
+    // return an error type instead of SFINAE.
     template <class _Sender, class _Env = __default_env>
-        requires(__with_tag_invoke<_Sender, _Env> ||          //
-                 __with_member_alias<_Sender> ||              //
-                 __awaitable<_Sender, __env_promise<_Env>> || //
-#if STDEXEC_LEGACY_R5_CONCEPTS()                              //
-                 __r7_style_sender<_Sender, _Env> ||          //
-#endif                                                        //
-                 __is_debug_env<_Env>)                        //
     constexpr auto operator()(_Sender&&, const _Env&) const noexcept
         -> decltype(__impl<_Sender, _Env>()())
     {
@@ -1253,23 +1799,23 @@
 
 /////////////////////////////////////////////////////////////////////////////
 // [execution.senders]
+namespace __detail
+{
 template <class _Sender>
 concept __enable_sender =                        //
     requires { typename _Sender::is_sender; } || //
     __awaitable<_Sender, __env_promise<empty_env>>;
+} // namespace __detail
 
 template <class _Sender>
-inline constexpr bool enable_sender = __enable_sender<_Sender>;
+inline constexpr bool enable_sender = __detail::__enable_sender<_Sender>;
 
-// NOT TO SPEC (YET)
-#if !STDEXEC_LEGACY_R5_CONCEPTS()
-// Here is the R7 sender concepts, not yet enabled.
-template <class _Sender>
-concept sender =                               //
-    enable_sender<__decay_t<_Sender>> &&       //
-    environment_provider<__cref_t<_Sender>> && //
-    move_constructible<__decay_t<_Sender>> &&  //
-    constructible_from<__decay_t<_Sender>, _Sender>;
+template <class _Sender, class _Env = empty_env>
+concept sender = enable_sender<__decay_t<_Sender>> &&                  //
+                 environment_provider<__cref_t<_Sender>> &&            //
+                 __detail::__consistent_completion_domains<_Sender> && //
+                 move_constructible<__decay_t<_Sender>> &&             //
+                 constructible_from<__decay_t<_Sender>, _Sender>;
 
 template <class _Sender, class _Env = empty_env>
 concept sender_in =    //
@@ -1277,40 +1823,10 @@
     requires(_Sender&& __sndr, _Env&& __env) {
         {
             get_completion_signatures((_Sender&&)__sndr, (_Env&&)__env)
-        } -> __valid_completion_signatures<_Env>;
+        } -> __valid_completion_signatures;
     };
 
-template <class _Sender, class _Env = empty_env>
-    requires sender_in<_Sender, _Env>
-using completion_signatures_of_t = __completion_signatures_of_t<_Sender, _Env>;
-
-#else
-
-template <class _Sender, class _Env = no_env>
-concept __sender = //
-    requires(_Sender&& __sndr, _Env&& __env) {
-        get_completion_signatures((_Sender&&)__sndr, (_Env&&)__env);
-    } && //
-    __valid_completion_signatures<__completion_signatures_of_t<_Sender, _Env>,
-                                  _Env>;
-
-template <class _Sender, class _Env = no_env>
-concept sender =
-    // NOT TO SPEC
-    // The sender related concepts are temporarily "in flight" being
-    // upgraded from P2300R5 to the get_env / enable_sender aware version
-    // in P2300R7.
-    __sender<_Sender> &&                       //
-    __sender<_Sender, _Env> &&                 //
-    environment_provider<__cref_t<_Sender>> && //
-    move_constructible<__decay_t<_Sender>> &&  //
-    constructible_from<__decay_t<_Sender>, _Sender>;
-
-template <class _Sender, class _Env = empty_env>
-concept sender_in =            //
-    __sender<_Sender, _Env> && //
-    sender<_Sender, _Env>;
-
+#if STDEXEC_ENABLE_EXTRA_TYPE_CHECKING()
 // __checked_completion_signatures is for catching logic bugs in a typed
 // sender's metadata. If sender<S> and sender_in<S, Ctx> are both true, then
 // they had better report the same metadata. This completion signatures wrapper
@@ -1319,19 +1835,20 @@
 auto __checked_completion_signatures(_Sender&& __sndr,
                                      const _Env& __env) noexcept
 {
-    using _WithEnv = __completion_signatures_of_t<_Sender, _Env>;
-    using _WithoutEnv = __completion_signatures_of_t<_Sender, no_env>;
-    static_assert(__one_of<_WithoutEnv, _WithEnv,
-                           dependent_completion_signatures<no_env>>);
-    stdexec::__debug_sender<_WithEnv>((_Sender&&)__sndr, __env);
-    return _WithEnv{};
+    using __completions_t = __completion_signatures_of_t<_Sender, _Env>;
+    stdexec::__debug_sender<__completions_t>((_Sender&&)__sndr, __env);
+    return __completions_t{};
 }
 
-template <class _Sender, class _Env = no_env>
+template <class _Sender, class _Env = empty_env>
     requires sender_in<_Sender, _Env>
 using completion_signatures_of_t =
     decltype(stdexec::__checked_completion_signatures(__declval<_Sender>(),
                                                       __declval<_Env>()));
+#else
+template <class _Sender, class _Env = empty_env>
+    requires sender_in<_Sender, _Env>
+using completion_signatures_of_t = __completion_signatures_of_t<_Sender, _Env>;
 #endif
 
 struct __not_a_variant
@@ -1440,11 +1957,11 @@
 using __count_of = __msuccess_or_t<__try_count_of<_Tag, _Sender, _Env>>;
 
 template <class _Tag, class _Sender, class _Env = __default_env>
-    requires __valid<__count_of, _Tag, _Sender, _Env>
+    requires __mvalid<__count_of, _Tag, _Sender, _Env>
 inline constexpr bool __sends = (__v<__count_of<_Tag, _Sender, _Env>> != 0);
 
 template <class _Sender, class _Env = __default_env>
-    requires __valid<__count_of, set_stopped_t, _Sender, _Env>
+    requires __mvalid<__count_of, set_stopped_t, _Sender, _Env>
 inline constexpr bool sends_stopped = __sends<set_stopped_t, _Sender, _Env>;
 
 template <class _Sender, class _Env = __default_env>
@@ -1456,13 +1973,14 @@
     value_types_of_t<_Sender, _Env, __types, __msingle>;
 
 template <class _Sender, class _Env = __default_env>
-concept __single_typed_sender = sender_in<_Sender, _Env> &&
-                                __valid<__single_sender_value_t, _Sender, _Env>;
+concept __single_typed_sender =
+    sender_in<_Sender, _Env> &&
+    __mvalid<__single_sender_value_t, _Sender, _Env>;
 
 template <class _Sender, class _Env = __default_env>
 concept __single_value_variant_sender =
     sender_in<_Sender, _Env> &&
-    __valid<__single_value_variant_sender_t, _Sender, _Env>;
+    __mvalid<__single_value_variant_sender_t, _Sender, _Env>;
 
 template <class... Errs>
 using __nofail = __mbool<sizeof...(Errs) == 0>;
@@ -1480,7 +1998,7 @@
 template <class _Error>
 using __default_set_error = completion_signatures<set_error_t(_Error)>;
 
-template <__is_completion_signatures... _Sigs>
+template <__valid_completion_signatures... _Sigs>
 using __ensure_concat_ =
     __minvoke<__mconcat<__q<completion_signatures>>, _Sigs...>;
 
@@ -1501,8 +2019,8 @@
 
 template <class _Sender, class _Env, class _Sigs, class _SetVal, class _SetErr,
           class _SetStp>
-    requires __valid<__compl_sigs_impl, _Sender, _Env, _Sigs, _SetVal, _SetErr,
-                     _SetStp>
+    requires __mvalid<__compl_sigs_impl, _Sender, _Env, _Sigs, _SetVal, _SetErr,
+                      _SetStp>
 extern __compl_sigs_impl<_Sender, _Env, _Sigs, _SetVal, _SetErr, _SetStp>
     __compl_sigs_v;
 
@@ -1511,25 +2029,6 @@
 using __compl_sigs_t =
     decltype(__compl_sigs_v<_Sender, _Env, _Sigs, _SetVal, _SetErr, _SetStp>);
 
-template <bool>
-struct __make_compl_sigs
-{
-    template <class _Sender, class _Env, class _Sigs, class _SetVal,
-              class _SetErr, class _SetStp>
-    using __f = __compl_sigs_t<_Sender, _Env, _Sigs, _SetVal, _SetErr, _SetStp>;
-};
-
-template <>
-struct __make_compl_sigs<true>
-{
-    template <class _Sender, class _Env, class _Sigs, class _SetVal,
-              class _SetErr, class _SetStp>
-    using __f = //
-        __msuccess_or_t<
-            __compl_sigs_t<_Sender, _Env, _Sigs, _SetVal, _SetErr, _SetStp>,
-            dependent_completion_signatures<_Env>>;
-};
-
 template <                                                      //
     class _Sender,                                              //
     class _Env = __default_env,                                 //
@@ -1538,8 +2037,8 @@
     class _SetError = __q<__default_set_error>,                 //
     class _SetStopped = completion_signatures<set_stopped_t()>> //
 using __try_make_completion_signatures =                        //
-    __minvoke<__make_compl_sigs<same_as<_Env, no_env>>, _Sender, _Env, _Sigs,
-              _SetValue, _SetError, _SetStopped>;
+    __meval<__compl_sigs_t, _Sender, _Env, _Sigs, _SetValue, _SetError,
+            _SetStopped>;
 } // namespace __compl_sigs
 
 using __compl_sigs::__try_make_completion_signatures;
@@ -1612,10 +2111,10 @@
 template <                                                                   //
     class _Sender,                                                           //
     class _Env = __default_env,                                              //
-    __valid_completion_signatures<_Env> _Sigs = completion_signatures<>,     //
+    __valid_completion_signatures _Sigs = completion_signatures<>,           //
     template <class...> class _SetValue = __compl_sigs::__default_set_value, //
     template <class> class _SetError = __compl_sigs::__default_set_error,    //
-    __valid_completion_signatures<_Env> _SetStopped =
+    __valid_completion_signatures _SetStopped =
         completion_signatures<set_stopped_t()>>
     requires sender_in<_Sender, _Env>
 using make_completion_signatures = //
@@ -1635,8 +2134,7 @@
 {
     template <class _Scheduler>
         requires tag_invocable<schedule_t, _Scheduler>
-    STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
-        auto
+    STDEXEC_ATTRIBUTE((host, device)) auto
         operator()(_Scheduler&& __sched) const
         noexcept(nothrow_tag_invocable<schedule_t, _Scheduler>)
     {
@@ -1677,7 +2175,7 @@
 template <class _Scheduler>
 concept __sender_has_completion_scheduler =
     requires(_Scheduler&& __sched,
-             const get_completion_scheduler_t<set_value_t>&& __tag) {
+             get_completion_scheduler_t<set_value_t>&& __tag) {
         {
             tag_invoke(std::move(__tag),
                        get_env(schedule((_Scheduler&&)__sched)))
@@ -1714,7 +2212,9 @@
 {
     template <class _Op>
         requires tag_invocable<start_t, _Op&>
-    void operator()(_Op& __op) const noexcept
+    STDEXEC_ATTRIBUTE((always_inline)) //
+        void
+        operator()(_Op& __op) const noexcept
     {
         static_assert(nothrow_tag_invocable<start_t, _Op&>);
         (void)tag_invoke(start_t{}, __op);
@@ -1778,7 +2278,21 @@
     ~__operation_base()
     {
         if (__coro_)
+        {
+#if STDEXEC_MSVC()
+            // MSVCBUG
+            // https://developercommunity.visualstudio.com/t/Double-destroy-of-a-local-in-coroutine-d/10456428
+
+            // Reassign __coro_ before calling destroy to make the mutation
+            // observable and to hopefully ensure that the compiler does not
+            // eliminate it.
+            auto __coro = __coro_;
+            __coro_ = {};
+            __coro.destroy();
+#else
             __coro_.destroy();
+#endif
+        }
     }
 
     friend void tag_invoke(start_t, __operation_base& __self) noexcept
@@ -1827,18 +2341,18 @@
         }
 
         template <class _Awaitable>
-        _Awaitable&& await_transform(_Awaitable&& __await) noexcept
+        _Awaitable&& await_transform(_Awaitable&& __awaitable) noexcept
         {
-            return (_Awaitable&&)__await;
+            return (_Awaitable&&)__awaitable;
         }
 
         template <class _Awaitable>
             requires tag_invocable<as_awaitable_t, _Awaitable, __t&>
-        auto await_transform(_Awaitable&& __await) //
+        auto await_transform(_Awaitable&& __awaitable) //
             noexcept(nothrow_tag_invocable<as_awaitable_t, _Awaitable, __t&>)
                 -> tag_invoke_result_t<as_awaitable_t, _Awaitable, __t&>
         {
-            return tag_invoke(as_awaitable, (_Awaitable&&)__await, *this);
+            return tag_invoke(as_awaitable, (_Awaitable&&)__awaitable, *this);
         }
 
         // Pass through the get_env receiver query
@@ -1890,19 +2404,22 @@
     }
 
     template <class _Awaitable, class _Receiver>
-    static __operation_t<_Receiver> __co_impl(_Awaitable __await,
-                                              _Receiver __rcvr)
+#if STDEXEC_GCC() && (__GNUC__ > 11)
+    __attribute__((__used__))
+#endif
+    static __operation_t<_Receiver>
+        __co_impl(_Awaitable __awaitable, _Receiver __rcvr)
     {
         using __result_t = __await_result_t<_Awaitable, __promise_t<_Receiver>>;
         std::exception_ptr __eptr;
         try
         {
             if constexpr (same_as<__result_t, void>)
-                co_await (co_await (_Awaitable&&) __await,
+                co_await (co_await (_Awaitable&&) __awaitable,
                           __co_call(set_value, (_Receiver&&)__rcvr));
             else
                 co_await __co_call(set_value, (_Receiver&&)__rcvr,
-                                   co_await (_Awaitable&&) __await);
+                                   co_await (_Awaitable&&) __awaitable);
         }
         catch (...)
         {
@@ -1923,10 +2440,10 @@
   public:
     template <class _Receiver, __awaitable<__promise_t<_Receiver>> _Awaitable>
         requires receiver_of<_Receiver, __completions_t<_Receiver, _Awaitable>>
-    __operation_t<_Receiver> operator()(_Awaitable&& __await,
+    __operation_t<_Receiver> operator()(_Awaitable&& __awaitable,
                                         _Receiver __rcvr) const
     {
-        return __co_impl((_Awaitable&&)__await, (_Receiver&&)__rcvr);
+        return __co_impl((_Awaitable&&)__awaitable, (_Receiver&&)__rcvr);
     }
 };
 } // namespace __connect_awaitable_
@@ -1944,54 +2461,81 @@
 {
 struct connect_t;
 
-template <class _Tp>
-STDEXEC_R5_SENDER_DEPRECATION_WARNING //
-    void
-    _PLEASE_UPDATE_YOUR_SENDER_TYPE()
-{}
-
-template <class _Tp>
-STDEXEC_R5_RECEIVER_DEPRECATION_WARNING //
-    void
-    _PLEASE_UPDATE_YOUR_RECEIVER_TYPE()
-{}
+template <class _Sender, class _Receiver>
+using __tfx_sender = //
+    transform_sender_result_t<__late_domain_of_t<_Sender, env_of_t<_Receiver&>>,
+                              _Sender, env_of_t<_Receiver&>>;
 
 template <class _Sender, class _Receiver>
-concept __connectable_with_tag_invoke =
+concept __connectable_with_tag_invoke_ =       //
     receiver<_Receiver> &&                     //
     sender_in<_Sender, env_of_t<_Receiver>> && //
     __receiver_from<_Receiver, _Sender> &&     //
     tag_invocable<connect_t, _Sender, _Receiver>;
 
+template <class _Sender, class _Receiver>
+concept __connectable_with_tag_invoke = //
+    __connectable_with_tag_invoke_<__tfx_sender<_Sender, _Receiver>, _Receiver>;
+
+template <class _Sender, class _Receiver>
+concept __connectable_with_co_await = //
+    __callable<__connect_awaitable_t, __tfx_sender<_Sender, _Receiver>,
+               _Receiver>;
+
 struct connect_t
 {
+    template <class _Sender, class _Env>
+    static constexpr bool __check_signatures()
+    {
+        if constexpr (sender_in<_Sender, _Env>)
+        {
+            // Instantiate __debug_sender via completion_signatures_of_t
+            // to check that the actual completions match the expected
+            // completions.
+            //
+            // Instantiate completion_signatures_of_t only if sender_in
+            // is true to workaround Clang not implementing CWG#2369 yet
+            // (connect() does have a constraint for _Sender satisfying
+            // sender_in).
+            using __checked_signatures
+                [[maybe_unused]] = completion_signatures_of_t<_Sender, _Env>;
+        }
+        return true;
+    }
+
     template <class _Sender, class _Receiver>
     static constexpr auto __select_impl() noexcept
     {
-        // Report that 2300R5-style senders and receivers are deprecated:
-        if constexpr (!enable_sender<__decay_t<_Sender>>)
-            _PLEASE_UPDATE_YOUR_SENDER_TYPE<__decay_t<_Sender>>();
+#if STDEXEC_ENABLE_EXTRA_TYPE_CHECKING()
+        static_assert(__check_signatures<_Sender, env_of_t<_Receiver>>());
+#endif
 
-        if constexpr (!enable_receiver<__decay_t<_Receiver>>)
-            _PLEASE_UPDATE_YOUR_RECEIVER_TYPE<__decay_t<_Receiver>>();
+        using _Domain = __late_domain_of_t<_Sender, env_of_t<_Receiver&>>;
+        constexpr bool _NothrowTfxSender =
+            __nothrow_callable<get_env_t, _Receiver&> &&
+            __nothrow_callable<transform_sender_t, _Domain, _Sender,
+                               env_of_t<_Receiver&>>;
+        using _TfxSender = __tfx_sender<_Sender, _Receiver&>;
 
         if constexpr (__connectable_with_tag_invoke<_Sender, _Receiver>)
         {
-            using _Result = tag_invoke_result_t<connect_t, _Sender, _Receiver>;
-            constexpr bool _Nothrow =
-                nothrow_tag_invocable<connect_t, _Sender, _Receiver>;
+            using _Result =
+                tag_invoke_result_t<connect_t, _TfxSender, _Receiver>;
+            constexpr bool _Nothrow = //
+                _NothrowTfxSender &&
+                nothrow_tag_invocable<connect_t, _TfxSender, _Receiver>;
             return static_cast<_Result (*)() noexcept(_Nothrow)>(nullptr);
         }
-        else if constexpr (__callable<__connect_awaitable_t, _Sender,
-                                      _Receiver>)
+        else if constexpr (__connectable_with_co_await<_Sender, _Receiver>)
         {
             using _Result =
-                __call_result_t<__connect_awaitable_t, _Sender, _Receiver>;
+                __call_result_t<__connect_awaitable_t, _TfxSender, _Receiver>;
             return static_cast<_Result (*)()>(nullptr);
         }
         else
         {
-            return static_cast<__debug::__debug_operation (*)() noexcept>(
+            using _Result = __debug::__debug_operation;
+            return static_cast<_Result (*)() noexcept(_NothrowTfxSender)>(
                 nullptr);
         }
     }
@@ -2001,33 +2545,42 @@
 
     template <sender _Sender, receiver _Receiver>
         requires __connectable_with_tag_invoke<_Sender, _Receiver> ||
-                 __callable<__connect_awaitable_t, _Sender, _Receiver> ||
+                 __connectable_with_co_await<_Sender, _Receiver> ||
                  __is_debug_env<env_of_t<_Receiver>>
     auto operator()(_Sender&& __sndr, _Receiver&& __rcvr) const
         noexcept(__nothrow_callable<__select_impl_t<_Sender, _Receiver>>)
             -> __call_result_t<__select_impl_t<_Sender, _Receiver>>
     {
+        using _TfxSender = __tfx_sender<_Sender, _Receiver&>;
+        auto&& __env = get_env(__rcvr);
+        auto __domain = __get_late_domain(__sndr, __env);
+
         if constexpr (__connectable_with_tag_invoke<_Sender, _Receiver>)
         {
             static_assert(
                 operation_state<
-                    tag_invoke_result_t<connect_t, _Sender, _Receiver>>,
+                    tag_invoke_result_t<connect_t, _TfxSender, _Receiver>>,
                 "stdexec::connect(sender, receiver) must return a type that "
                 "satisfies the operation_state concept");
-            return tag_invoke(connect_t{}, (_Sender&&)__sndr,
-                              (_Receiver&&)__rcvr);
+            return tag_invoke(
+                connect_t{},
+                transform_sender(__domain, (_Sender&&)__sndr, __env),
+                (_Receiver&&)__rcvr);
         }
-        else if constexpr (__callable<__connect_awaitable_t, _Sender,
-                                      _Receiver>)
+        else if constexpr (__connectable_with_co_await<_Sender, _Receiver>)
         {
-            return __connect_awaitable((_Sender&&)__sndr, (_Receiver&&)__rcvr);
+            return __connect_awaitable( //
+                transform_sender(__domain, (_Sender&&)__sndr, __env),
+                (_Receiver&&)__rcvr);
         }
         else
         {
-            // This should generate an instantiate backtrace that contains
+            // This should generate an instantiation backtrace that contains
             // useful debugging information.
             using __tag_invoke::tag_invoke;
-            tag_invoke(*this, (_Sender&&)__sndr, (_Receiver&&)__rcvr);
+            tag_invoke(*this,
+                       transform_sender(__domain, (_Sender&&)__sndr, __env),
+                       (_Receiver&&)__rcvr);
         }
     }
 
@@ -2044,15 +2597,12 @@
 /////////////////////////////////////////////////////////////////////////////
 // [exec.snd]
 template <class _Sender, class _Receiver>
-concept sender_to =
-    receiver<_Receiver> &&           //
-    __sender<_Sender,
-             env_of_t<_Receiver>> && // NOT TO SPEC: for simpler diagnostics
-    sender_in<_Sender, env_of_t<_Receiver>> && //
-    __receiver_from<_Receiver, _Sender> &&     //
-    requires(_Sender&& __sndr, _Receiver&& __rcvr) {
-        connect((_Sender&&)__sndr, (_Receiver&&)__rcvr);
-    };
+concept sender_to = receiver<_Receiver> &&                     //
+                    sender_in<_Sender, env_of_t<_Receiver>> && //
+                    __receiver_from<_Receiver, _Sender> &&     //
+                    requires(_Sender&& __sndr, _Receiver&& __rcvr) {
+                        connect((_Sender&&)__sndr, (_Receiver&&)__rcvr);
+                    };
 
 template <class _Tag, class... _Args>
 _Tag __tag_of_sig_(_Tag (*)(_Args...));
@@ -2066,12 +2616,6 @@
                                   __tag_of_sig_t<_SetSig>, _Sender, _Env,
                                   __qf<__tag_of_sig_t<_SetSig>>, __q<__types>>>;
 
-template <class _Fun, class _CPO, class _Sender, class... _As>
-concept __tag_invocable_with_completion_scheduler =
-    __has_completion_scheduler<_Sender, _CPO> &&
-    tag_invocable<_Fun, __completion_scheduler_for<_Sender, _CPO>, _Sender,
-                  _As...>;
-
 #if !STDEXEC_STD_NO_COROUTINES_
 /////////////////////////////////////////////////////////////////////////////
 // stdexec::as_awaitable [execution.coro_utils.as_awaitable]
@@ -2159,7 +2703,8 @@
 
 template <class _Sender, class _Promise>
 using __value_t =
-    __decay_t<__single_sender_value_t<_Sender, env_of_t<_Promise&>>>;
+    __decay_t<__value_types_of_t<_Sender, env_of_t<_Promise&>,
+                                 __msingle_or<void>, __msingle_or<void>>>;
 
 template <class _Sender, class _Promise>
 using __receiver_t =
@@ -2227,7 +2772,8 @@
 
 template <class _Sender, class _Promise>
 concept __awaitable_sender =
-    __single_typed_sender<_Sender, env_of_t<_Promise&>> && //
+    sender_in<_Sender, env_of_t<_Promise&>> &&             //
+    __mvalid<__value_t, _Sender, _Promise> &&              //
     sender_to<_Sender, __receiver_t<_Sender, _Promise>> && //
     requires(_Promise& __promise) {
         {
@@ -2432,75 +2978,83 @@
 using __with_awaitable_senders::with_awaitable_senders;
 #endif
 
+namespace
+{
+inline constexpr auto __ref = []<class _Ty>(_Ty& __ty) noexcept {
+    return [__ty = &__ty]() noexcept -> decltype(auto) { return (*__ty); };
+};
+}
+
+template <class _Ty>
+using __ref_t = decltype(__ref(__declval<_Ty&>()));
+
 /////////////////////////////////////////////////////////////////////////////
 // NOT TO SPEC: __submit
 namespace __submit_
 {
-template <class _ReceiverId>
-struct __operation_base;
-
-template <class _ReceiverId>
-struct __operation_base
-{
-    using _Receiver = __t<_ReceiverId>;
-    _Receiver __rcvr_;
-
-    using __delete_fn_t = void(__operation_base<_ReceiverId>*) noexcept;
-    __delete_fn_t* __delete_;
-};
-
-template <class _ReceiverId>
+template <class _OpRef>
 struct __receiver
 {
-    using _Receiver = stdexec::__t<_ReceiverId>;
+    using is_receiver = void;
+    using __t = __receiver;
+    using __id = __receiver;
 
-    struct __t
+    using _Operation = __decay_t<__call_result_t<_OpRef>>;
+    using _Receiver = stdexec::__t<__mapply<__q<__msecond>, _Operation>>;
+
+    _OpRef __opref_;
+
+    // Forward all the receiver ops, and delete the operation state.
+    template <__completion_tag _Tag, class... _As>
+        requires __callable<_Tag, _Receiver, _As...>
+    friend void tag_invoke(_Tag __tag, __receiver&& __self,
+                           _As&&... __as) noexcept
     {
-        using is_receiver = void;
-        using __id = __receiver;
-        __operation_base<_ReceiverId>* __op_state_;
+        __tag((_Receiver&&)__self.__opref_().__rcvr_, (_As&&)__as...);
+        __self.__delete_op();
+    }
 
-        // Forward all the receiver ops, and delete the operation state.
-        template <__completion_tag _Tag, class... _As>
-            requires __callable<_Tag, _Receiver, _As...>
-        friend void tag_invoke(
-            _Tag __tag, __t&& __self,
-            _As&&... __as) noexcept(__nothrow_callable<_Tag, _Receiver, _As...>)
+    void __delete_op() noexcept
+    {
+        _Operation* __op = &__opref_();
+        if constexpr (__callable<get_allocator_t, env_of_t<_Receiver>>)
         {
-            // Delete the state as cleanup:
-            auto __g = __scope_guard{__self.__op_state_->__delete_,
-                                     __self.__op_state_};
-            return __tag((_Receiver&&)__self.__op_state_->__rcvr_,
-                         (_As&&)__as...);
+            auto&& __env = get_env(__op->__rcvr_);
+            auto __alloc = get_allocator(__env);
+            using _Alloc = decltype(__alloc);
+            using _OpAlloc = typename std::allocator_traits<
+                _Alloc>::template rebind_alloc<_Operation>;
+            _OpAlloc __op_alloc{__alloc};
+            std::allocator_traits<_OpAlloc>::destroy(__op_alloc, __op);
+            std::allocator_traits<_OpAlloc>::deallocate(__op_alloc, __op, 1);
         }
+        else
+        {
+            delete __op;
+        }
+    }
 
-        // Forward all receiever queries.
-        friend auto tag_invoke(get_env_t, const __t& __self) noexcept
-            -> env_of_t<_Receiver>
-        {
-            return get_env(__self.__op_state_->__rcvr_);
-        }
-    };
+    // Forward all receiever queries.
+    friend auto tag_invoke(get_env_t, const __receiver& __self) noexcept
+        -> env_of_t<_Receiver&>
+    {
+        return get_env(__self.__opref_().__rcvr_);
+    }
 };
-template <class _ReceiverId>
-using __receiver_t = __t<__receiver<_ReceiverId>>;
 
 template <class _SenderId, class _ReceiverId>
-struct __operation : __operation_base<_ReceiverId>
+struct __operation
 {
     using _Sender = stdexec::__t<_SenderId>;
     using _Receiver = stdexec::__t<_ReceiverId>;
+    using __receiver_t = __receiver<__ref_t<__operation>>;
 
-    connect_result_t<_Sender, __receiver_t<_ReceiverId>> __op_state_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Receiver __rcvr_;
+    connect_result_t<_Sender, __receiver_t> __op_state_;
 
-    template <__decays_to<_Receiver> _CvrefReceiver>
-    __operation(_Sender&& __sndr, _CvrefReceiver&& __rcvr) :
-        __operation_base<_ReceiverId>{
-            (_CvrefReceiver&&)__rcvr,
-            [](__operation_base<_ReceiverId>* __self) noexcept {
-        delete static_cast<__operation*>(__self);
-    }},
-        __op_state_(connect((_Sender&&)__sndr, __receiver_t<_ReceiverId>{this}))
+    __operation(_Sender&& __sndr, _Receiver __rcvr) :
+        __rcvr_((_Receiver&&)__rcvr),
+        __op_state_(connect((_Sender&&)__sndr, __receiver_t{__ref(*this)}))
     {}
 };
 
@@ -2509,9 +3063,36 @@
     template <receiver _Receiver, sender_to<_Receiver> _Sender>
     void operator()(_Sender&& __sndr, _Receiver __rcvr) const noexcept(false)
     {
-        start((new __operation<__id<_Sender>, __id<_Receiver>>{
-                   (_Sender&&)__sndr, (_Receiver&&)__rcvr})
-                  ->__op_state_);
+        if constexpr (__callable<get_allocator_t, env_of_t<_Receiver>>)
+        {
+            auto&& __env = get_env(__rcvr);
+            auto __alloc = get_allocator(__env);
+            using _Alloc = decltype(__alloc);
+            using _Op = __operation<__id<_Sender>, __id<_Receiver>>;
+            using _OpAlloc = typename std::allocator_traits<
+                _Alloc>::template rebind_alloc<_Op>;
+            _OpAlloc __op_alloc{__alloc};
+            auto __op = std::allocator_traits<_OpAlloc>::allocate(__op_alloc,
+                                                                  1);
+            try
+            {
+                std::allocator_traits<_OpAlloc>::construct(
+                    __op_alloc, __op, (_Sender&&)__sndr, (_Receiver&&)__rcvr);
+                start(__op->__op_state_);
+            }
+            catch (...)
+            {
+                std::allocator_traits<_OpAlloc>::deallocate(__op_alloc, __op,
+                                                            1);
+                throw;
+            }
+        }
+        else
+        {
+            start((new __operation<__id<_Sender>, __id<_Receiver>>{
+                       (_Sender&&)__sndr, (_Receiver&&)__rcvr})
+                      ->__op_state_);
+        }
     }
 };
 } // namespace __submit_
@@ -2521,52 +3102,61 @@
 
 namespace __inln
 {
+struct __scheduler;
+
+template <class _Receiver>
+struct __op : __immovable
+{
+    _Receiver __recv_;
+
+    friend void tag_invoke(start_t, __op& __self) noexcept
+    {
+        set_value((_Receiver&&)__self.__recv_);
+    }
+};
+
+struct __schedule_t
+{
+    static auto get_env(__ignore) noexcept
+        -> __env::__prop<__scheduler(get_completion_scheduler_t<set_value_t>)>;
+
+    using __compl_sigs = stdexec::completion_signatures<set_value_t()>;
+    static __compl_sigs get_completion_signatures(__ignore, __ignore);
+
+    template <receiver_of<__compl_sigs> _Receiver>
+    static auto
+        connect(__ignore,
+                _Receiver __rcvr) noexcept(__nothrow_decay_copyable<_Receiver>)
+    {
+        return __op<_Receiver>{{}, (_Receiver&&)__rcvr};
+    }
+};
+
 struct __scheduler
 {
     using __t = __scheduler;
     using __id = __scheduler;
 
-    template <class _Receiver>
-    struct __op : __immovable
+    STDEXEC_ATTRIBUTE((host, device))
+    friend auto tag_invoke(schedule_t, __scheduler)
     {
-        _Receiver __recv_;
+        return __make_sexpr<__schedule_t>();
+    }
 
-        friend void tag_invoke(start_t, __op& __self) noexcept
-        {
-            set_value((_Receiver&&)__self.__recv_);
-        }
-    };
-
-    struct __sender
+    friend forward_progress_guarantee
+        tag_invoke(get_forward_progress_guarantee_t, __scheduler) noexcept
     {
-        using __t = __sender;
-        using __id = __sender;
-        using is_sender = void;
-        using completion_signatures =
-            stdexec::completion_signatures<set_value_t()>;
-
-        template <receiver_of<completion_signatures> _Receiver>
-        friend __op<_Receiver> tag_invoke(connect_t, __sender, _Receiver __rcvr)
-        {
-            return {{}, (_Receiver&&)__rcvr};
-        }
-
-        friend auto tag_invoke(get_env_t, __sender) noexcept
-        {
-            return __env::__env_fn{
-                [](get_completion_scheduler_t<set_value_t>) noexcept {
-                return __scheduler{};
-            }};
-        }
-    };
-
-    friend __sender tag_invoke(schedule_t, __scheduler)
-    {
-        return {};
+        return forward_progress_guarantee::weakly_parallel;
     }
 
     bool operator==(const __scheduler&) const noexcept = default;
 };
+
+inline auto __schedule_t::get_env(__ignore) noexcept
+    -> __env::__prop<__scheduler(get_completion_scheduler_t<set_value_t>)>
+{
+    return __mkprop(__scheduler{}, get_completion_scheduler<set_value_t>);
+}
 } // namespace __inln
 
 /////////////////////////////////////////////////////////////////////////////
@@ -2582,7 +3172,7 @@
     {
         using is_receiver = void;
         using __id = __detached_receiver;
-        STDEXEC_NO_UNIQUE_ADDRESS _Env __env_;
+        STDEXEC_ATTRIBUTE((no_unique_address)) _Env __env_;
 
         template <same_as<set_value_t> _Tag, class... _As>
         friend void tag_invoke(_Tag, __t&&, _As&&...) noexcept
@@ -2605,52 +3195,43 @@
         }
     };
 };
-template <class _Env>
+template <class _Env = empty_env>
 using __detached_receiver_t = __t<__detached_receiver<__id<__decay_t<_Env>>>>;
 
-struct start_detached_t;
-
-// When looking for user-defined customizations of start_detached, these
-// are the signatures to test against, in order:
-using _Sender = __0;
-using _Env = __1;
-using __cust_sigs = //
-    __types<tag_invoke_t(start_detached_t, _Sender),
-            tag_invoke_t(start_detached_t, _Sender, _Env),
-            tag_invoke_t(start_detached_t, get_scheduler_t(_Env&), _Sender),
-            tag_invoke_t(start_detached_t, get_scheduler_t(_Env&), _Sender,
-                         _Env)>;
-
-template <class _Sender, class _Env>
-inline constexpr bool __is_start_detached_customized =
-    __minvocable<__which<__cust_sigs>, _Sender, _Env>;
-
-struct __submit_detached
-{
-    template <class _Sender, class _Env>
-    void operator()(_Sender&& __sndr, _Env&& __env) const
-    {
-        __submit((_Sender&&)__sndr, __detached_receiver_t<_Env>{(_Env&&)__env});
-    }
-};
-
-template <class _Sender, class _Env>
-using __dispatcher_for =
-    __make_dispatcher<__cust_sigs, __mconst<__submit_detached>, _Sender, _Env>;
-
 struct start_detached_t
 {
-    template <sender _Sender, class _Env = empty_env>
-        requires sender_to<_Sender, __detached_receiver_t<_Env>> ||
-                 __is_start_detached_customized<_Sender, _Env>
-    void operator()(_Sender&& __sndr, _Env&& __env = _Env{}) const noexcept(
-        __nothrow_callable<__dispatcher_for<_Sender, _Env>, _Sender, _Env>)
+    template <sender_in<empty_env> _Sender>
+        requires __callable<apply_sender_t, __early_domain_of_t<_Sender>,
+                            start_detached_t, _Sender>
+    void operator()(_Sender&& __sndr) const
     {
-        using _Dispatcher = __dispatcher_for<_Sender, _Env>;
-        // The selected implementation should return void
-        static_assert(
-            same_as<void, __call_result_t<_Dispatcher, _Sender, _Env>>);
-        _Dispatcher{}((_Sender&&)__sndr, (_Env&&)__env);
+        auto __domain = __get_early_domain(__sndr);
+        stdexec::apply_sender(__domain, *this, (_Sender&&)__sndr);
+    }
+
+    template <class _Env, sender_in<_Env> _Sender>
+        requires __callable<apply_sender_t, __late_domain_of_t<_Sender, _Env>,
+                            start_detached_t, _Sender, _Env>
+    void operator()(_Sender&& __sndr, _Env&& __env) const
+    {
+        auto __domain = __get_late_domain(__sndr, __env);
+        stdexec::apply_sender(__domain, *this, (_Sender&&)__sndr,
+                              (_Env&&)__env);
+    }
+
+    using _Sender = __0;
+    using __legacy_customizations_t =
+        __types<tag_invoke_t(start_detached_t,
+                             get_completion_scheduler_t<set_value_t>(
+                                 get_env_t(const _Sender&)),
+                             _Sender),
+                tag_invoke_t(start_detached_t, _Sender)>;
+
+    template <class _Sender, class _Env = empty_env>
+        requires sender_to<_Sender, __detached_receiver_t<_Env>>
+    void apply_sender(_Sender&& __sndr, _Env&& __env = {}) const
+    {
+        __submit((_Sender&&)__sndr, __detached_receiver_t<_Env>{(_Env&&)__env});
     }
 };
 } // namespace __start_detached
@@ -2662,10 +3243,7 @@
 // [execution.senders.factories]
 namespace __just
 {
-template <class _Tag, class... _Ts>
-using __completion_signatures_ = completion_signatures<_Tag(_Ts...)>;
-
-template <class _ReceiverId, class _Tag, class... _Ts>
+template <class _ReceiverId, class _Tag, class _Tuple>
 struct __operation
 {
     using _Receiver = stdexec::__t<_ReceiverId>;
@@ -2673,126 +3251,108 @@
     struct __t : __immovable
     {
         using __id = __operation;
-        std::tuple<_Ts...> __vals_;
+        _Tuple __vals_;
         _Receiver __rcvr_;
 
         friend void tag_invoke(start_t, __t& __op_state) noexcept
         {
-            std::apply(
-                [&__op_state](_Ts&... __ts) {
-                _Tag{}((_Receiver&&)__op_state.__rcvr_, (_Ts&&)__ts...);
+            using __tag_t = _Tag;
+            using __receiver_t = _Receiver;
+            __apply(
+                [&__op_state]<class... _Ts>(_Ts&... __ts) {
+                __tag_t()((__receiver_t&&)__op_state.__rcvr_, (_Ts&&)__ts...);
             },
                 __op_state.__vals_);
         }
     };
 };
 
-template <class _Tag, class... _Ts>
-struct __basic_sender
+template <class _SetTag, class _Receiver>
+struct __connect_fn
 {
-    template <class _Receiver>
-    using __operation_t =
-        stdexec::__t<__operation<stdexec::__id<_Receiver>, _Tag, _Ts...>>;
+    _Receiver& __rcvr_;
 
-    struct __t
+    template <class _Tuple>
+    auto operator()(__ignore, _Tuple&& __tup) const
+        noexcept(__nothrow_decay_copyable<_Tuple>)
+            -> __t<__operation<__id<_Receiver>, _SetTag, __decay_t<_Tuple>>>
     {
-        using __id = __basic_sender;
-        using is_sender = void;
-        using completion_signatures = __completion_signatures_<_Tag, _Ts...>;
-
-        std::tuple<_Ts...> __vals_;
-
-        template <receiver_of<completion_signatures> _Receiver>
-            requires(copy_constructible<_Ts> && ...)
-        friend auto tag_invoke(connect_t, const __t& __sndr,
-                               _Receiver __rcvr) //
-            noexcept((std::is_nothrow_copy_constructible_v<_Ts> && ...))
-                -> __operation_t<_Receiver>
-        {
-            return {{}, __sndr.__vals_, (_Receiver&&)__rcvr};
-        }
-
-        template <receiver_of<completion_signatures> _Receiver>
-        friend auto tag_invoke(connect_t, __t&& __sndr, _Receiver __rcvr) //
-            noexcept((std::is_nothrow_move_constructible_v<_Ts> && ...))
-                -> __operation_t<_Receiver>
-        {
-            return {{}, ((__t&&)__sndr).__vals_, (_Receiver&&)__rcvr};
-        }
-
-        friend empty_env tag_invoke(get_env_t, const __t&) noexcept
-        {
-            return {};
-        }
-    };
+        return {{}, (_Tuple&&)__tup, (_Receiver&&)__rcvr_};
+    }
 };
 
-template <class... _Values>
-struct __sender
+template <class _JustTag, class _SetTag>
+struct __just_impl
 {
-    using __base = stdexec::__t<__basic_sender<set_value_t, _Values...>>;
+    template <class _Sender>
+    using __compl_sigs =       //
+        completion_signatures< //
+            __mapply<          //
+                __qf<_SetTag>, __decay_t<__data_of<_Sender>>>>;
 
-    struct __t : __base
+    template <sender_expr_for<_JustTag> _Sender>
+    static __compl_sigs<_Sender> get_completion_signatures(_Sender&&, __ignore)
     {
-        using __id = __sender;
-    };
-};
+        return {};
+    }
 
-template <class _Error>
-struct __error_sender
-{
-    using __base = stdexec::__t<__basic_sender<set_error_t, _Error>>;
-
-    struct __t : __base
+    template <sender_expr_for<_JustTag> _Sender,
+              receiver_of<__compl_sigs<_Sender>> _Receiver>
+    static auto connect(_Sender&& __sndr, _Receiver __rcvr) noexcept(
+        __nothrow_callable<__sexpr_apply_t, _Sender,
+                           __connect_fn<_SetTag, _Receiver>>)
+        -> __call_result_t<__sexpr_apply_t, _Sender,
+                           __connect_fn<_SetTag, _Receiver>>
     {
-        using __id = __error_sender;
-    };
+        return __sexpr_apply((_Sender&&)__sndr,
+                             __connect_fn<_SetTag, _Receiver>{__rcvr});
+    }
+
+    static empty_env get_env(__ignore) noexcept
+    {
+        return {};
+    }
 };
 
-struct __stopped_sender : __t<__basic_sender<set_stopped_t>>
-{
-    using __id = __stopped_sender;
-    using __t = __stopped_sender;
-};
-
-inline constexpr struct __just_t
+struct just_t : __just_impl<just_t, set_value_t>
 {
     template <__movable_value... _Ts>
-    STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
-        __t<__sender<__decay_t<_Ts>...>>
-        operator()(_Ts&&... __ts) const
-        noexcept((__nothrow_constructible_from<__decay_t<_Ts>, _Ts> && ...))
+    STDEXEC_ATTRIBUTE((host, device))
+    auto operator()(_Ts&&... __ts) const
+        noexcept((__nothrow_decay_copyable<_Ts> && ...))
     {
-        return {{{(_Ts&&)__ts...}}};
+        return __make_sexpr<just_t>(__decayed_tuple<_Ts...>{(_Ts&&)__ts...});
     }
-} just{};
+};
 
-inline constexpr struct __just_error_t
+struct just_error_t : __just_impl<just_error_t, set_error_t>
 {
     template <__movable_value _Error>
-    STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
-        __t<__error_sender<__decay_t<_Error>>>
-        operator()(_Error&& __err) const
-        noexcept(__nothrow_constructible_from<__decay_t<_Error>, _Error>)
+    STDEXEC_ATTRIBUTE((host, device))
+    auto operator()(_Error&& __err) const
+        noexcept(__nothrow_decay_copyable<_Error>)
     {
-        return {{{(_Error&&)__err}}};
+        return __make_sexpr<just_error_t>(
+            __decayed_tuple<_Error>{(_Error&&)__err});
     }
-} just_error{};
+};
 
-inline constexpr struct __just_stopped_t
+struct just_stopped_t : __just_impl<just_stopped_t, set_stopped_t>
 {
-    STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
-        __stopped_sender
-        operator()() const noexcept
+    STDEXEC_ATTRIBUTE((host, device)) auto operator()() const noexcept
     {
-        return {{}};
+        return __make_sexpr<just_stopped_t>(__decayed_tuple<>());
     }
-} just_stopped{};
+};
 } // namespace __just
 
-using __just::just;
-using __just::just_error;
-using __just::just_stopped;
+using __just::just_error_t;
+using __just::just_stopped_t;
+using __just::just_t;
+
+inline constexpr just_t just{};
+inline constexpr just_error_t just_error{};
+inline constexpr just_stopped_t just_stopped{};
 
 /////////////////////////////////////////////////////////////////////////////
 // [execution.execute]
@@ -2838,21 +3398,27 @@
 {
     template <scheduler _Scheduler, class _Fun>
         requires __callable<_Fun&> && move_constructible<_Fun>
-    void operator()(_Scheduler&& __sched, _Fun __fun) const //
-        noexcept(noexcept(__submit(schedule((_Scheduler&&)__sched),
-                                   __as_receiver<_Fun>{(_Fun&&)__fun})))
+    void operator()(_Scheduler&& __sched, _Fun __fun) const noexcept(false)
     {
-        (void)__submit(schedule((_Scheduler&&)__sched),
-                       __as_receiver<_Fun>{(_Fun&&)__fun});
+        // Look for a legacy customization
+        if constexpr (tag_invocable<execute_t, _Scheduler, _Fun>)
+        {
+            tag_invoke(execute_t{}, (_Scheduler&&)__sched, (_Fun&&)__fun);
+        }
+        else
+        {
+            auto __domain = query_or(get_domain, __sched, default_domain());
+            stdexec::apply_sender(__domain, *this,
+                                  schedule((_Scheduler&&)__sched),
+                                  (_Fun&&)__fun);
+        }
     }
 
-    template <scheduler _Scheduler, class _Fun>
-        requires __callable<_Fun&> && move_constructible<_Fun> &&
-                 tag_invocable<execute_t, _Scheduler, _Fun>
-    void operator()(_Scheduler&& __sched, _Fun __fun) const
-        noexcept(nothrow_tag_invocable<execute_t, _Scheduler, _Fun>)
+    template <sender_of<set_value_t()> _Sender, class _Fun>
+        requires __callable<_Fun&> && move_constructible<_Fun>
+    void apply_sender(_Sender&& __sndr, _Fun __fun) const noexcept(false)
     {
-        (void)tag_invoke(execute_t{}, (_Scheduler&&)__sched, (_Fun&&)__fun);
+        __submit((_Sender&&)__sndr, __as_receiver<_Fun>{(_Fun&&)__fun});
     }
 };
 } // namespace __execute_
@@ -2886,13 +3452,14 @@
 template <class _T0, class _T1>
 struct __compose : sender_adaptor_closure<__compose<_T0, _T1>>
 {
-    STDEXEC_NO_UNIQUE_ADDRESS _T0 __t0_;
-    STDEXEC_NO_UNIQUE_ADDRESS _T1 __t1_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _T0 __t0_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _T1 __t1_;
 
     template <sender _Sender>
         requires __callable<_T0, _Sender> &&
                  __callable<_T1, __call_result_t<_T0, _Sender>>
-    __call_result_t<_T1, __call_result_t<_T0, _Sender>>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+        __call_result_t<_T1, __call_result_t<_T0, _Sender>>
         operator()(_Sender&& __sndr) &&
     {
         return ((_T1&&)__t1_)(((_T0&&)__t0_)((_Sender&&)__sndr));
@@ -2901,7 +3468,8 @@
     template <sender _Sender>
         requires __callable<const _T0&, _Sender> &&
                  __callable<const _T1&, __call_result_t<const _T0&, _Sender>>
-    __call_result_t<_T1, __call_result_t<_T0, _Sender>>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+        __call_result_t<_T1, __call_result_t<_T0, _Sender>>
         operator()(_Sender&& __sndr) const&
     {
         return __t1_(__t0_((_Sender&&)__sndr));
@@ -2913,6 +3481,7 @@
 {};
 
 template <sender _Sender, __sender_adaptor_closure_for<_Sender> _Closure>
+STDEXEC_ATTRIBUTE((always_inline)) //
 __call_result_t<_Closure, _Sender> operator|(_Sender&& __sndr,
                                              _Closure&& __clsur)
 {
@@ -2920,6 +3489,7 @@
 }
 
 template <__sender_adaptor_closure _T0, __sender_adaptor_closure _T1>
+STDEXEC_ATTRIBUTE((always_inline)) //
 __compose<__decay_t<_T0>, __decay_t<_T1>> operator|(_T0&& __t0, _T1&& __t1)
 {
     return {{}, (_T0&&)__t0, (_T1&&)__t1};
@@ -2928,18 +3498,19 @@
 template <class _Fun, class... _As>
 struct __binder_back : sender_adaptor_closure<__binder_back<_Fun, _As...>>
 {
-    STDEXEC_NO_UNIQUE_ADDRESS _Fun __fun_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Fun __fun_;
     std::tuple<_As...> __as_;
 
     template <sender _Sender>
         requires __callable<_Fun, _Sender, _As...>
-    STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
+    STDEXEC_ATTRIBUTE((host, device, always_inline)) //
         __call_result_t<_Fun, _Sender, _As...>
         operator()(_Sender&& __sndr) && noexcept(
             __nothrow_callable<_Fun, _Sender, _As...>)
     {
-        return std::apply(
-            [&__sndr, this](_As&... __as) {
+        return __apply(
+            [&__sndr,
+             this](_As&... __as) -> __call_result_t<_Fun, _Sender, _As...> {
             return ((_Fun&&)__fun_)((_Sender&&)__sndr, (_As&&)__as...);
         },
             __as_);
@@ -2947,13 +3518,14 @@
 
     template <sender _Sender>
         requires __callable<const _Fun&, _Sender, const _As&...>
-    STDEXEC_DETAIL_CUDACC_HOST_DEVICE       //
+    STDEXEC_ATTRIBUTE((host, device))
         __call_result_t<const _Fun&, _Sender, const _As&...>
         operator()(_Sender&& __sndr) const& //
         noexcept(__nothrow_callable<const _Fun&, _Sender, const _As&...>)
     {
-        return std::apply(
-            [&__sndr, this](const _As&... __as) {
+        return __apply(
+            [&__sndr, this](const _As&... __as)
+                -> __call_result_t<const _Fun&, _Sender, const _As&...> {
             return __fun_((_Sender&&)__sndr, __as...);
         },
             __as_);
@@ -2968,9 +3540,8 @@
 // A derived-to-base cast that works even when the base is not
 // accessible from derived.
 template <class _Tp, class _Up>
-STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
-    __copy_cvref_t<_Up&&, _Tp>
-    __c_cast(_Up&& u) noexcept
+STDEXEC_ATTRIBUTE((host, device))
+__copy_cvref_t<_Up&&, _Tp> __c_cast(_Up&& u) noexcept
     requires __decays_to<_Tp, _Tp>
 {
     static_assert(std::is_reference_v<__copy_cvref_t<_Up&&, _Tp>>);
@@ -2984,7 +3555,9 @@
 {};
 
 struct __receiver : __nope
-{};
+{
+    using is_receiver = void;
+};
 
 template <same_as<set_error_t> _Tag>
 void tag_invoke(_Tag, __receiver, std::exception_ptr) noexcept;
@@ -3006,26 +3579,23 @@
         {}
 
       private:
-        STDEXEC_NO_UNIQUE_ADDRESS _Base __base_;
+        STDEXEC_ATTRIBUTE((no_unique_address)) _Base __base_;
 
       protected:
-        STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
-            _Base&
-            base() & noexcept
+        STDEXEC_ATTRIBUTE((host, device, always_inline)) //
+        _Base& base() & noexcept
         {
             return __base_;
         }
 
-        STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
-            const _Base&
-            base() const& noexcept
+        STDEXEC_ATTRIBUTE((host, device, always_inline)) //
+        const _Base& base() const& noexcept
         {
             return __base_;
         }
 
-        STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
-            _Base&&
-            base() && noexcept
+        STDEXEC_ATTRIBUTE((host, device, always_inline)) //
+        _Base&& base() && noexcept
         {
             return (_Base&&)__base_;
         }
@@ -3047,8 +3617,8 @@
 // but 'int(type::existing_member_function)' is an error (as desired).
 #define _DISPATCH_MEMBER(_TAG)                                                 \
     template <class _Self, class... _Ts>                                       \
-    STDEXEC_DETAIL_CUDACC_HOST_DEVICE static auto __call_##_TAG(               \
-        _Self&& __self, _Ts&&... __ts) noexcept                                \
+    STDEXEC_ATTRIBUTE((host, device, always_inline))                           \
+    static auto __call_##_TAG(_Self&& __self, _Ts&&... __ts) noexcept          \
         -> decltype(((_Self&&)__self)._TAG((_Ts&&)__ts...))                    \
     {                                                                          \
         static_assert(noexcept(((_Self&&)__self)._TAG((_Ts&&)__ts...)));       \
@@ -3096,9 +3666,8 @@
         using __base_t = __minvoke<__get_base_t, _Dp&&>;
 
         template <class _Dp>
-        STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
-            static __base_t<_Dp>
-            __get_base(_Dp&& __self) noexcept
+        STDEXEC_ATTRIBUTE((host, device))
+        static __base_t<_Dp> __get_base(_Dp&& __self) noexcept
         {
             if constexpr (__has_base)
             {
@@ -3111,10 +3680,10 @@
         }
 
         template <same_as<set_value_t> _SetValue, class... _As>
-        STDEXEC_DETAIL_CUDACC_HOST_DEVICE                                    //
-            friend auto
-            tag_invoke(_SetValue, _Derived&& __self, _As&&... __as) noexcept //
-            -> __msecond<                                                    //
+        STDEXEC_ATTRIBUTE((host, device, always_inline))
+        friend auto tag_invoke(_SetValue, _Derived&& __self,
+                               _As&&... __as) noexcept //
+            -> __msecond<                              //
                 __if_c<same_as<set_value_t, _SetValue>>,
                 decltype(_CALL_MEMBER(set_value, (_Derived&&)__self,
                                       (_As&&)__as...))>
@@ -3128,8 +3697,8 @@
                   class... _As>
             requires _MISSING_MEMBER
         (_Dp, set_value) &&
-            tag_invocable<_SetValue, __base_t<_Dp>,
-                          _As...> STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
+            tag_invocable<_SetValue, __base_t<_Dp>, _As...> STDEXEC_ATTRIBUTE(
+                (host, device, always_inline)) //
             friend void tag_invoke(_SetValue, _Derived&& __self,
                                    _As&&... __as) noexcept
         {
@@ -3137,10 +3706,10 @@
         }
 
         template <same_as<set_error_t> _SetError, class _Error>
-        STDEXEC_DETAIL_CUDACC_HOST_DEVICE                                     //
-            friend auto
-            tag_invoke(_SetError, _Derived&& __self, _Error&& __err) noexcept //
-            -> __msecond<                                                     //
+        STDEXEC_ATTRIBUTE((host, device, always_inline)) //
+        friend auto tag_invoke(_SetError, _Derived&& __self,
+                               _Error&& __err) noexcept  //
+            -> __msecond<                                //
                 __if_c<same_as<set_error_t, _SetError>>,
                 decltype(_CALL_MEMBER(set_error, (_Derived&&)__self,
                                       (_Error&&)__err))>
@@ -3154,8 +3723,8 @@
                   class _Dp = _Derived>
             requires _MISSING_MEMBER
         (_Dp, set_error) &&
-            tag_invocable<_SetError, __base_t<_Dp>,
-                          _Error> STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
+            tag_invocable<_SetError, __base_t<_Dp>, _Error> STDEXEC_ATTRIBUTE(
+                (host, device, always_inline)) //
             friend void tag_invoke(_SetError, _Derived&& __self,
                                    _Error&& __err) noexcept
         {
@@ -3163,10 +3732,9 @@
         }
 
         template <same_as<set_stopped_t> _SetStopped, class _Dp = _Derived>
-        STDEXEC_DETAIL_CUDACC_HOST_DEVICE                       //
-            friend auto
-            tag_invoke(_SetStopped, _Derived&& __self) noexcept //
-            -> __msecond<                                       //
+        STDEXEC_ATTRIBUTE((host, device, always_inline))                //
+        friend auto tag_invoke(_SetStopped, _Derived&& __self) noexcept //
+            -> __msecond<                                               //
                 __if_c<same_as<set_stopped_t, _SetStopped>>,
                 decltype(_CALL_MEMBER(set_stopped, (_Dp&&)__self))>
         {
@@ -3178,8 +3746,8 @@
         template <same_as<set_stopped_t> _SetStopped, class _Dp = _Derived>
             requires _MISSING_MEMBER
         (_Dp, set_stopped) &&
-            tag_invocable<_SetStopped,
-                          __base_t<_Dp>> STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
+            tag_invocable<_SetStopped, __base_t<_Dp>> STDEXEC_ATTRIBUTE(
+                (host, device, always_inline)) //
             friend void tag_invoke(_SetStopped, _Derived&& __self) noexcept
         {
             stdexec::set_stopped(__get_base((_Derived&&)__self));
@@ -3187,9 +3755,8 @@
 
         // Pass through the get_env receiver query
         template <same_as<get_env_t> _GetEnv, class _Dp = _Derived>
-        STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
-            friend auto
-            tag_invoke(_GetEnv, const _Derived& __self) noexcept
+        STDEXEC_ATTRIBUTE((host, device, always_inline)) //
+        friend auto tag_invoke(_GetEnv, const _Derived& __self) noexcept
             -> decltype(_CALL_MEMBER(get_env, (const _Dp&)__self))
         {
             static_assert(noexcept(_CALL_MEMBER(get_env, __self)));
@@ -3198,7 +3765,7 @@
 
         template <same_as<get_env_t> _GetEnv, class _Dp = _Derived>
             requires _MISSING_MEMBER
-        (_Dp, get_env) STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
+        (_Dp, get_env) STDEXEC_ATTRIBUTE((host, device, always_inline)) //
             friend auto tag_invoke(_GetEnv, const _Derived& __self) noexcept
             -> env_of_t<__base_t<const _Dp&>>
         {
@@ -3222,7 +3789,7 @@
 concept __receiver_of_invoke_result = //
     receiver_of<_Receiver, completion_signatures<
                                __minvoke<__remove<void, __qf<set_value_t>>,
-                                         std::invoke_result_t<_Fun, _As...>>>>;
+                                         __invoke_result_t<_Fun, _As...>>>>;
 
 template <bool _CanThrow = false, class _Receiver, class _Fun, class... _As>
 void __set_value_invoke(_Receiver&& __rcvr, _Fun&& __fun,
@@ -3230,15 +3797,15 @@
 {
     if constexpr (_CanThrow || __nothrow_invocable<_Fun, _As...>)
     {
-        if constexpr (same_as<void, std::invoke_result_t<_Fun, _As...>>)
+        if constexpr (same_as<void, __invoke_result_t<_Fun, _As...>>)
         {
-            std::invoke((_Fun&&)__fun, (_As&&)__as...);
+            __invoke((_Fun&&)__fun, (_As&&)__as...);
             set_value((_Receiver&&)__rcvr);
         }
         else
         {
             set_value((_Receiver&&)__rcvr,
-                      std::invoke((_Fun&&)__fun, (_As&&)__as...));
+                      __invoke((_Fun&&)__fun, (_As&&)__as...));
         }
     }
     else
@@ -3281,7 +3848,7 @@
 };
 
 template <class _Fun, class... _Args>
-    requires invocable<_Fun, _Args...>
+    requires __invocable<_Fun, _Args...>
 using __non_throwing_ = __mbool<__nothrow_invocable<_Fun, _Args...>>;
 
 template <class _Tag, class _Fun, class _Sender, class _Env, class _Catch>
@@ -3293,10 +3860,40 @@
          completion_signatures<>, __with_exception_ptr>;
 
 template <class _Fun, class... _Args>
-    requires invocable<_Fun, _Args...>
+    requires __invocable<_Fun, _Args...>
 using __set_value_invoke_t = //
     completion_signatures<__minvoke<__remove<void, __qf<set_value_t>>,
-                                    std::invoke_result_t<_Fun, _Args...>>>;
+                                    __invoke_result_t<_Fun, _Args...>>>;
+
+struct __default_get_env_fn
+{
+    // BUGBUG This should hide all but the forwarding queries
+    template <class _Sender>
+    env_of_t<_Sender> operator()(__ignore, __ignore,
+                                 const _Sender& __child) const noexcept
+    {
+        return get_env(__child);
+    }
+
+    template <class... _Senders>
+        requires(sizeof...(_Senders) != 1)
+    empty_env operator()(__ignore, __ignore, const _Senders&...) const noexcept
+    {
+        return {};
+    }
+};
+
+template <class _Tag>
+struct __with_default_get_env
+{
+    template <sender_expr_for<_Tag> _Sender>
+    static auto get_env(const _Sender& __sndr) noexcept
+        -> __call_result_t<__sexpr_apply_t, const _Sender&,
+                           __default_get_env_fn>
+    {
+        return __sexpr_apply(__sndr, __default_get_env_fn());
+    }
+};
 
 /////////////////////////////////////////////////////////////////////////////
 // [execution.senders.adaptors.then]
@@ -3310,7 +3907,7 @@
     struct __data
     {
         _Receiver __rcvr_;
-        STDEXEC_NO_UNIQUE_ADDRESS _Fun __fun_;
+        STDEXEC_ATTRIBUTE((no_unique_address)) _Fun __fun_;
     };
 
     struct __t
@@ -3322,7 +3919,7 @@
         // Customize set_value by invoking the invocable and passing the result
         // to the downstream receiver
         template <__same_as<set_value_t> _Tag, class... _As>
-            requires invocable<_Fun, _As...> &&
+            requires __invocable<_Fun, _As...> &&
                      __receiver_of_invoke_result<_Receiver, _Fun, _As...>
         friend void tag_invoke(_Tag, __t&& __self, _As&&... __as) noexcept
         {
@@ -3346,7 +3943,7 @@
     };
 };
 
-template <class _Sender, class _ReceiverId, class _Fun>
+template <class _CvrefSender, class _ReceiverId, class _Fun>
 struct __operation
 {
     using _Receiver = stdexec::__t<_ReceiverId>;
@@ -3357,14 +3954,14 @@
     {
         using __id = __operation;
         typename __receiver_id::__data __data_;
-        connect_result_t<_Sender, __receiver_t> __op_;
+        connect_result_t<_CvrefSender, __receiver_t> __op_;
 
-        __t(_Sender&& __sndr, _Receiver __rcvr, _Fun __fun) //
-            noexcept(__nothrow_decay_copyable<_Receiver>    //
-                     && __nothrow_decay_copyable<_Fun>      //
-                     && __nothrow_connectable<_Sender, __receiver_t>) :
+        __t(_CvrefSender&& __sndr, _Receiver __rcvr, _Fun __fun) //
+            noexcept(__nothrow_decay_copyable<_Receiver>         //
+                     && __nothrow_decay_copyable<_Fun>           //
+                     && __nothrow_connectable<_CvrefSender, __receiver_t>) :
             __data_{(_Receiver&&)__rcvr, (_Fun&&)__fun},
-            __op_(connect((_Sender&&)__sndr, __receiver_t{&__data_}))
+            __op_(connect((_CvrefSender&&)__sndr, __receiver_t{&__data_}))
         {}
 
         friend void tag_invoke(start_t, __t& __self) noexcept
@@ -3378,109 +3975,84 @@
     "In stdexec::then(Sender, Function)..."__csz;
 using __on_not_callable = __callable_error<__then_context>;
 
-template <class _SenderId, class _Fun>
-struct __sender
+template <class _Fun, class _CvrefSender, class _Env>
+using __completion_signatures_t = //
+    __try_make_completion_signatures<
+        _CvrefSender, _Env,
+        __with_error_invoke_t<set_value_t, _Fun, _CvrefSender, _Env,
+                              __on_not_callable>,
+        __mbind_front<__mtry_catch_q<__set_value_invoke_t, __on_not_callable>,
+                      _Fun>>;
+
+template <class _Receiver>
+struct __connect_fn
 {
-    using _Sender = stdexec::__t<_SenderId>;
-    template <class _Receiver>
-    using __receiver = stdexec::__t<__receiver<stdexec::__id<_Receiver>, _Fun>>;
-    template <class _Self, class _Receiver>
-    using __operation =
-        stdexec::__t<__operation<__copy_cvref_t<_Self, _Sender>,
-                                 stdexec::__id<_Receiver>, _Fun>>;
+    _Receiver& __rcvr_;
 
-    struct __t
+    template <class _Fun, class _Child>
+    using __operation_t =
+        __t<__operation<_Child, __id<_Receiver>, __decay_t<_Fun>>>;
+
+    template <class _Fun, class _Child>
+    auto operator()(__ignore, _Fun&& __fun, _Child&& __child) const
+        noexcept(__nothrow_constructible_from<__operation_t<_Fun, _Child>,
+                                              _Child, _Receiver, _Fun>)
+            -> __operation_t<_Fun, _Child>
     {
-        using __id = __sender;
-        using is_sender = void;
-        STDEXEC_NO_UNIQUE_ADDRESS _Sender __sndr_;
-        STDEXEC_NO_UNIQUE_ADDRESS _Fun __fun_;
-
-        template <class _Self, class _Env>
-        using __completion_signatures = //
-            __try_make_completion_signatures<
-                __copy_cvref_t<_Self, _Sender>, _Env,
-                __with_error_invoke_t<set_value_t, _Fun,
-                                      __copy_cvref_t<_Self, _Sender>, _Env,
-                                      __on_not_callable>,
-                __mbind_front<
-                    __mtry_catch_q<__set_value_invoke_t, __on_not_callable>,
-                    _Fun>>;
-
-        template <__decays_to<__t> _Self, receiver _Receiver>
-            requires sender_to<__copy_cvref_t<_Self, _Sender>,
-                               __receiver<_Receiver>>
-        friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr) //
-            noexcept(__nothrow_constructible_from<
-                     __operation<_Self, _Receiver>,
-                     __copy_cvref_t<_Self, _Sender>, _Receiver&&,
-                     __copy_cvref_t<_Self, _Fun>>)
-                -> __operation<_Self, _Receiver>
-        {
-            return {((_Self&&)__self).__sndr_, (_Receiver&&)__rcvr,
-                    ((_Self&&)__self).__fun_};
-        }
-
-        template <__decays_to<__t> _Self, class _Env>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
-            -> dependent_completion_signatures<_Env>;
-
-        template <__decays_to<__t> _Self, class _Env>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
-            -> __completion_signatures<_Self, _Env>
-            requires true;
-
-        friend auto tag_invoke(get_env_t, const __t& __self) noexcept
-            -> env_of_t<const _Sender&>
-        {
-            return get_env(__self.__sndr_);
-        }
-    };
+        return __operation_t<_Fun, _Child>{(_Child&&)__child,
+                                           (_Receiver&&)__rcvr_, (_Fun&&)__fun};
+    }
 };
 
-struct then_t
+////////////////////////////////////////////////////////////////////////////////////////////////
+struct then_t : __with_default_get_env<then_t>
 {
-    template <class _Sender, class _Fun>
-    using __sender = __t<__sender<stdexec::__id<__decay_t<_Sender>>, _Fun>>;
-
     template <sender _Sender, __movable_value _Fun>
-        requires(!__tag_invocable_with_completion_scheduler<then_t, set_value_t,
-                                                            _Sender, _Fun>) &&
-                (!tag_invocable<then_t, _Sender, _Fun>) &&
-                sender<__sender<_Sender, _Fun>>
-    __sender<_Sender, _Fun> operator()(_Sender&& __sndr, _Fun __fun) const
+    auto operator()(_Sender&& __sndr, _Fun __fun) const
     {
-        return __sender<_Sender, _Fun>{(_Sender&&)__sndr, (_Fun&&)__fun};
+        auto __domain = __get_early_domain(__sndr);
+        return stdexec::transform_sender(
+            __domain, __make_sexpr<then_t>((_Fun&&)__fun, (_Sender&&)__sndr));
     }
 
-    template <sender _Sender, __movable_value _Fun>
-        requires __tag_invocable_with_completion_scheduler<then_t, set_value_t,
-                                                           _Sender, _Fun>
-    sender auto operator()(_Sender&& __sndr, _Fun __fun) const
-        noexcept(nothrow_tag_invocable<
-                 then_t, __completion_scheduler_for<_Sender, set_value_t>,
-                 _Sender, _Fun>)
-    {
-        auto __sched = get_completion_scheduler<set_value_t>(get_env(__sndr));
-        return tag_invoke(then_t{}, std::move(__sched), (_Sender&&)__sndr,
-                          (_Fun&&)__fun);
-    }
-
-    template <sender _Sender, __movable_value _Fun>
-        requires(!__tag_invocable_with_completion_scheduler<then_t, set_value_t,
-                                                            _Sender, _Fun>) &&
-                tag_invocable<then_t, _Sender, _Fun>
-    sender auto operator()(_Sender&& __sndr, _Fun __fun) const
-        noexcept(nothrow_tag_invocable<then_t, _Sender, _Fun>)
-    {
-        return tag_invoke(then_t{}, (_Sender&&)__sndr, (_Fun&&)__fun);
-    }
-
-    template <class _Fun>
+    template <__movable_value _Fun>
+    STDEXEC_ATTRIBUTE((always_inline)) //
     __binder_back<then_t, _Fun> operator()(_Fun __fun) const
     {
         return {{}, {}, {(_Fun&&)__fun}};
     }
+
+    using _Sender = __1;
+    using _Fun = __0;
+    using __legacy_customizations_t =
+        __types<tag_invoke_t(then_t,
+                             get_completion_scheduler_t<set_value_t>(
+                                 get_env_t(_Sender&)),
+                             _Sender, _Fun),
+                tag_invoke_t(then_t, _Sender, _Fun)>;
+
+#if STDEXEC_FRIENDSHIP_IS_LEXICAL()
+  private:
+    template <class...>
+    friend struct stdexec::__sexpr;
+#endif
+
+    template <sender_expr_for<then_t> _Sender, class _Env>
+    static auto get_completion_signatures(_Sender&&, _Env&&)
+        -> __completion_signatures_t<__decay_t<__data_of<_Sender>>,
+                                     __child_of<_Sender>, _Env>
+    {
+        return {};
+    }
+
+    template <sender_expr_for<then_t> _Sender, receiver _Receiver>
+    static auto connect(_Sender&& __sndr, _Receiver __rcvr) noexcept(
+        __nothrow_callable<__sexpr_apply_t, _Sender, __connect_fn<_Receiver>>)
+        -> __call_result_t<__sexpr_apply_t, _Sender, __connect_fn<_Receiver>>
+    {
+        return __sexpr_apply((_Sender&&)__sndr,
+                             __connect_fn<_Receiver>{__rcvr});
+    }
 };
 } // namespace __then
 
@@ -3496,39 +4068,69 @@
 {
     using _Receiver = stdexec::__t<_ReceiverId>;
 
+    struct __data
+    {
+        _Receiver __rcvr_;
+        STDEXEC_ATTRIBUTE((no_unique_address)) _Fun __fun_;
+    };
+
     struct __t
     {
         using is_receiver = void;
         using __id = __receiver;
+        __data* __op_;
 
-        _Receiver __rcvr_;
-        STDEXEC_NO_UNIQUE_ADDRESS _Fun __fun_;
-
-        template <__one_of<set_value_t, set_stopped_t> _Tag, same_as<__t> _Self,
-                  class... _Args>
-            requires __callable<_Tag, _Receiver, _Args...>
-        friend void tag_invoke(_Tag, _Self&& __self, _Args&&... __args) noexcept
-        {
-            _Tag{}((_Receiver&&)__self.__rcvr_, (_Args&&)__args...);
-        }
-
-        // Customize set_error by invoking the invocable and passing the result
-        // to the base class
-        template <same_as<set_error_t> _Tag, __decays_to<__t> _Self,
-                  class _Error>
-            requires invocable<_Fun, _Error> &&
+        // Customize set_value by invoking the invocable and passing the result
+        // to the downstream receiver
+        template <__same_as<set_error_t> _Tag, class _Error>
+            requires __invocable<_Fun, _Error> &&
                      __receiver_of_invoke_result<_Receiver, _Fun, _Error>
-        friend void tag_invoke(_Tag, _Self&& __self, _Error&& __error) noexcept
+        friend void tag_invoke(_Tag, __t&& __self, _Error&& __error) noexcept
         {
-            stdexec::__set_value_invoke((_Receiver&&)__self.__rcvr_,
-                                        (_Fun&&)__self.__fun_,
+            stdexec::__set_value_invoke((_Receiver&&)__self.__op_->__rcvr_,
+                                        (_Fun&&)__self.__op_->__fun_,
                                         (_Error&&)__error);
         }
 
-        friend env_of_t<_Receiver> tag_invoke(get_env_t,
-                                              const __t& __self) noexcept
+        template <__one_of<set_value_t, set_stopped_t> _Tag, class... _As>
+            requires __callable<_Tag, _Receiver, _As...>
+        friend void tag_invoke(_Tag __tag, __t&& __self, _As&&... __as) noexcept
         {
-            return get_env(__self.__rcvr_);
+            __tag((_Receiver&&)__self.__op_->__rcvr_, (_As&&)__as...);
+        }
+
+        friend auto tag_invoke(get_env_t, const __t& __self) noexcept
+            -> env_of_t<const _Receiver&>
+        {
+            return get_env(__self.__op_->__rcvr_);
+        }
+    };
+};
+
+template <class _CvrefSender, class _ReceiverId, class _Fun>
+struct __operation
+{
+    using _Receiver = stdexec::__t<_ReceiverId>;
+    using __receiver_id = __receiver<_ReceiverId, _Fun>;
+    using __receiver_t = stdexec::__t<__receiver_id>;
+
+    struct __t : __immovable
+    {
+        using __id = __operation;
+        typename __receiver_id::__data __data_;
+        connect_result_t<_CvrefSender, __receiver_t> __op_;
+
+        __t(_CvrefSender&& __sndr, _Receiver __rcvr, _Fun __fun) //
+            noexcept(__nothrow_decay_copyable<_Receiver>         //
+                     && __nothrow_decay_copyable<_Fun>           //
+                     && __nothrow_connectable<_CvrefSender, __receiver_t>) :
+            __data_{(_Receiver&&)__rcvr, (_Fun&&)__fun},
+            __op_(connect((_CvrefSender&&)__sndr, __receiver_t{&__data_}))
+        {}
+
+        friend void tag_invoke(start_t, __t& __self) noexcept
+        {
+            start(__self.__op_);
         }
     };
 };
@@ -3537,107 +4139,86 @@
     "In stdexec::upon_error(Sender, Function)..."__csz;
 using __on_not_callable = __callable_error<__upon_error_context>;
 
-template <class _SenderId, class _Fun>
-struct __sender
+template <class _Fun, class _CvrefSender, class _Env>
+using __completion_signatures_t = //
+    __try_make_completion_signatures<
+        _CvrefSender, _Env,
+        __with_error_invoke_t<set_error_t, _Fun, _CvrefSender, _Env,
+                              __on_not_callable>,
+        __q<__compl_sigs::__default_set_value>,
+        __mbind_front<__mtry_catch_q<__set_value_invoke_t, __on_not_callable>,
+                      _Fun>>;
+
+template <class _Receiver>
+struct __connect_fn
 {
-    using _Sender = stdexec::__t<_SenderId>;
+    _Receiver& __rcvr_;
 
-    template <class _Receiver>
-    using __receiver = stdexec::__t<__receiver<__id<_Receiver>, _Fun>>;
+    template <class _Fun, class _Child>
+    using __operation_t =
+        __t<__operation<_Child, __id<_Receiver>, __decay_t<_Fun>>>;
 
-    struct __t
+    template <class _Fun, class _Child>
+    auto operator()(__ignore, _Fun&& __fun, _Child&& __child) const
+        noexcept(__nothrow_constructible_from<__operation_t<_Fun, _Child>,
+                                              _Child, _Receiver, _Fun>)
+            -> __operation_t<_Fun, _Child>
     {
-        using __id = __sender;
-        using is_sender = void;
-
-        STDEXEC_NO_UNIQUE_ADDRESS _Sender __sndr_;
-        STDEXEC_NO_UNIQUE_ADDRESS _Fun __fun_;
-
-        template <class _Self, class _Env>
-        using __completion_signatures = //
-            __try_make_completion_signatures<
-                __copy_cvref_t<_Self, _Sender>, _Env,
-                __with_error_invoke_t<set_error_t, _Fun,
-                                      __copy_cvref_t<_Self, _Sender>, _Env,
-                                      __on_not_callable>,
-                __q<__compl_sigs::__default_set_value>,
-                __mbind_front_q<__set_value_invoke_t, _Fun>>;
-
-        template <__decays_to<__t> _Self, receiver _Receiver>
-            requires sender_to<__copy_cvref_t<_Self, _Sender>,
-                               __receiver<_Receiver>>
-        friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr) //
-            noexcept(__nothrow_connectable<__copy_cvref_t<_Self, _Sender>,
-                                           __receiver<_Receiver>>)
-                -> connect_result_t<__copy_cvref_t<_Self, _Sender>,
-                                    __receiver<_Receiver>>
-        {
-            return stdexec::connect(
-                ((_Self&&)__self).__sndr_,
-                __receiver<_Receiver>{(_Receiver&&)__rcvr,
-                                      ((_Self&&)__self).__fun_});
-        }
-
-        template <__decays_to<__t> _Self, class _Env>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
-            -> dependent_completion_signatures<_Env>;
-        template <__decays_to<__t> _Self, class _Env>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
-            -> __completion_signatures<_Self, _Env>
-            requires true;
-
-        friend auto tag_invoke(get_env_t, const __t& __self) noexcept
-            -> env_of_t<const _Sender&>
-        {
-            return get_env(__self.__sndr_);
-        }
-    };
+        return __operation_t<_Fun, _Child>{(_Child&&)__child,
+                                           (_Receiver&&)__rcvr_, (_Fun&&)__fun};
+    }
 };
 
-struct upon_error_t
+////////////////////////////////////////////////////////////////////////////////////////////////
+struct upon_error_t : __with_default_get_env<upon_error_t>
 {
-    template <class _Sender, class _Fun>
-    using __sender = __t<__sender<stdexec::__id<__decay_t<_Sender>>, _Fun>>;
-
     template <sender _Sender, __movable_value _Fun>
-        requires __tag_invocable_with_completion_scheduler<
-            upon_error_t, set_error_t, _Sender, _Fun>
-    sender auto operator()(_Sender&& __sndr, _Fun __fun) const
-        noexcept(nothrow_tag_invocable<
-                 upon_error_t, __completion_scheduler_for<_Sender, set_error_t>,
-                 _Sender, _Fun>)
+    auto operator()(_Sender&& __sndr, _Fun __fun) const
     {
-        auto __sched = get_completion_scheduler<set_error_t>(
-            get_env(__sndr)); // TODO ADD TEST!
-        return tag_invoke(upon_error_t{}, std::move(__sched), (_Sender&&)__sndr,
-                          (_Fun&&)__fun);
+        auto __domain = __get_early_domain(__sndr);
+        return stdexec::transform_sender(
+            __domain,
+            __make_sexpr<upon_error_t>((_Fun&&)__fun, (_Sender&&)__sndr));
     }
 
-    template <sender _Sender, __movable_value _Fun>
-        requires(!__tag_invocable_with_completion_scheduler<
-                    upon_error_t, set_error_t, _Sender, _Fun>) &&
-                tag_invocable<upon_error_t, _Sender, _Fun>
-    sender auto operator()(_Sender&& __sndr, _Fun __fun) const
-        noexcept(nothrow_tag_invocable<upon_error_t, _Sender, _Fun>)
-    {
-        return tag_invoke(upon_error_t{}, (_Sender&&)__sndr, (_Fun&&)__fun);
-    }
-
-    template <sender _Sender, __movable_value _Fun>
-        requires(!__tag_invocable_with_completion_scheduler<
-                    upon_error_t, set_error_t, _Sender, _Fun>) &&
-                (!tag_invocable<upon_error_t, _Sender, _Fun>) &&
-                sender<__sender<_Sender, _Fun>>
-    __sender<_Sender, _Fun> operator()(_Sender&& __sndr, _Fun __fun) const
-    {
-        return __sender<_Sender, _Fun>{(_Sender&&)__sndr, (_Fun&&)__fun};
-    }
-
-    template <class _Fun>
+    template <__movable_value _Fun>
+    STDEXEC_ATTRIBUTE((always_inline)) //
     __binder_back<upon_error_t, _Fun> operator()(_Fun __fun) const
     {
         return {{}, {}, {(_Fun&&)__fun}};
     }
+
+    using _Sender = __1;
+    using _Fun = __0;
+    using __legacy_customizations_t =
+        __types<tag_invoke_t(upon_error_t,
+                             get_completion_scheduler_t<set_value_t>(
+                                 get_env_t(_Sender&)),
+                             _Sender, _Fun),
+                tag_invoke_t(upon_error_t, _Sender, _Fun)>;
+
+#if STDEXEC_FRIENDSHIP_IS_LEXICAL()
+  private:
+    template <class...>
+    friend struct stdexec::__sexpr;
+#endif
+
+    template <sender_expr_for<upon_error_t> _Sender, class _Env>
+    static auto get_completion_signatures(_Sender&&, _Env&&)
+        -> __completion_signatures_t<__decay_t<__data_of<_Sender>>,
+                                     __child_of<_Sender>, _Env>
+    {
+        return {};
+    }
+
+    template <sender_expr_for<upon_error_t> _Sender, receiver _Receiver>
+    static auto connect(_Sender&& __sndr, _Receiver __rcvr) noexcept(
+        __nothrow_callable<__sexpr_apply_t, _Sender, __connect_fn<_Receiver>>)
+        -> __call_result_t<__sexpr_apply_t, _Sender, __connect_fn<_Receiver>>
+    {
+        return __sexpr_apply((_Sender&&)__sndr,
+                             __connect_fn<_Receiver>{__rcvr});
+    }
 };
 } // namespace __upon_error
 
@@ -3653,32 +4234,68 @@
 {
     using _Receiver = stdexec::__t<_ReceiverId>;
 
+    struct __data
+    {
+        _Receiver __rcvr_;
+        STDEXEC_ATTRIBUTE((no_unique_address)) _Fun __fun_;
+    };
+
     struct __t
     {
         using is_receiver = void;
         using __id = __receiver;
-        _Receiver __rcvr_;
-        STDEXEC_NO_UNIQUE_ADDRESS _Fun __fun_;
+        __data* __op_;
 
-        template <__one_of<set_value_t, set_error_t> _Tag, same_as<__t> _Self,
-                  class... _Args>
-            requires __callable<_Tag, _Receiver, _Args...>
-        friend void tag_invoke(_Tag, _Self&& __self, _Args&&... __args) noexcept
-        {
-            _Tag{}((_Receiver&&)__self.__rcvr_, (_Args&&)__args...);
-        }
-
-        template <same_as<set_stopped_t> _Tag>
+        // Customize set_value by invoking the invocable and passing the result
+        // to the downstream receiver
+        template <__same_as<set_stopped_t> _Tag>
+            requires __invocable<_Fun> &&
+                     __receiver_of_invoke_result<_Receiver, _Fun>
         friend void tag_invoke(_Tag, __t&& __self) noexcept
         {
-            stdexec::__set_value_invoke((_Receiver&&)__self.__rcvr_,
-                                        (_Fun&&)__self.__fun_);
+            stdexec::__set_value_invoke((_Receiver&&)__self.__op_->__rcvr_,
+                                        (_Fun&&)__self.__op_->__fun_);
         }
 
-        friend env_of_t<_Receiver> tag_invoke(get_env_t,
-                                              const __t& __self) noexcept
+        template <__one_of<set_value_t, set_error_t> _Tag, class... _As>
+            requires __callable<_Tag, _Receiver, _As...>
+        friend void tag_invoke(_Tag __tag, __t&& __self, _As&&... __as) noexcept
         {
-            return get_env(__self.__rcvr_);
+            __tag((_Receiver&&)__self.__op_->__rcvr_, (_As&&)__as...);
+        }
+
+        friend auto tag_invoke(get_env_t, const __t& __self) noexcept
+            -> env_of_t<const _Receiver&>
+        {
+            return get_env(__self.__op_->__rcvr_);
+        }
+    };
+};
+
+template <class _CvrefSender, class _ReceiverId, class _Fun>
+struct __operation
+{
+    using _Receiver = stdexec::__t<_ReceiverId>;
+    using __receiver_id = __receiver<_ReceiverId, _Fun>;
+    using __receiver_t = stdexec::__t<__receiver_id>;
+
+    struct __t : __immovable
+    {
+        using __id = __operation;
+        typename __receiver_id::__data __data_;
+        connect_result_t<_CvrefSender, __receiver_t> __op_;
+
+        __t(_CvrefSender&& __sndr, _Receiver __rcvr, _Fun __fun) //
+            noexcept(__nothrow_decay_copyable<_Receiver>         //
+                     && __nothrow_decay_copyable<_Fun>           //
+                     && __nothrow_connectable<_CvrefSender, __receiver_t>) :
+            __data_{(_Receiver&&)__rcvr, (_Fun&&)__fun},
+            __op_(connect((_CvrefSender&&)__sndr, __receiver_t{&__data_}))
+        {}
+
+        friend void tag_invoke(start_t, __t& __self) noexcept
+        {
+            start(__self.__op_);
         }
     };
 };
@@ -3687,109 +4304,88 @@
     "In stdexec::upon_stopped(Sender, Function)..."__csz;
 using __on_not_callable = __callable_error<__upon_stopped_context>;
 
-template <class _SenderId, class _Fun>
-struct __sender
+template <class _Fun, class _CvrefSender, class _Env>
+using __completion_signatures_t = //
+    __try_make_completion_signatures<
+        _CvrefSender, _Env,
+        __with_error_invoke_t<set_stopped_t, _Fun, _CvrefSender, _Env,
+                              __on_not_callable>,
+        __q<__compl_sigs::__default_set_value>,
+        __q<__compl_sigs::__default_set_error>, __set_value_invoke_t<_Fun>>;
+
+template <class _Receiver>
+struct __connect_fn
 {
-    using _Sender = stdexec::__t<_SenderId>;
+    _Receiver& __rcvr_;
 
-    template <class _Receiver>
-    using __receiver = stdexec::__t<__receiver<__id<_Receiver>, _Fun>>;
+    template <class _Fun, class _Child>
+    using __operation_t =
+        __t<__operation<_Child, __id<_Receiver>, __decay_t<_Fun>>>;
 
-    struct __t
+    template <class _Fun, class _Child>
+    auto operator()(__ignore, _Fun&& __fun, _Child&& __child) const
+        noexcept(__nothrow_constructible_from<__operation_t<_Fun, _Child>,
+                                              _Child, _Receiver, _Fun>)
+            -> __operation_t<_Fun, _Child>
     {
-        using __id = __sender;
-        using is_sender = void;
-
-        STDEXEC_NO_UNIQUE_ADDRESS _Sender __sndr_;
-        STDEXEC_NO_UNIQUE_ADDRESS _Fun __fun_;
-
-        template <class _Self, class _Env>
-        using __completion_signatures = //
-            __try_make_completion_signatures<
-                __copy_cvref_t<_Self, _Sender>, _Env,
-                __with_error_invoke_t<set_stopped_t, _Fun,
-                                      __copy_cvref_t<_Self, _Sender>, _Env,
-                                      __on_not_callable>,
-                __q<__compl_sigs::__default_set_value>,
-                __q<__compl_sigs::__default_set_error>,
-                __set_value_invoke_t<_Fun>>;
-
-        template <__decays_to<__t> _Self, receiver _Receiver>
-            requires __receiver_of_invoke_result<_Receiver, _Fun> &&
-                     sender_to<__copy_cvref_t<_Self, _Sender>,
-                               __receiver<_Receiver>>
-        friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr) //
-            noexcept(__nothrow_connectable<_Sender, __receiver<_Receiver>>)
-                -> connect_result_t<__copy_cvref_t<_Self, _Sender>,
-                                    __receiver<_Receiver>>
-        {
-            return stdexec::connect(
-                ((_Self&&)__self).__sndr_,
-                __receiver<_Receiver>{(_Receiver&&)__rcvr,
-                                      ((_Self&&)__self).__fun_});
-        }
-
-        template <__decays_to<__t> _Self, class _Env>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
-            -> dependent_completion_signatures<_Env>;
-        template <__decays_to<__t> _Self, class _Env>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
-            -> __completion_signatures<_Self, _Env>
-            requires true;
-
-        friend auto tag_invoke(get_env_t, const __t& __self) noexcept
-            -> env_of_t<const _Sender&>
-        {
-            return get_env(__self.__sndr_);
-        }
-    };
+        return __operation_t<_Fun, _Child>{(_Child&&)__child,
+                                           (_Receiver&&)__rcvr_, (_Fun&&)__fun};
+    }
 };
 
-struct upon_stopped_t
+////////////////////////////////////////////////////////////////////////////////////////////////
+struct upon_stopped_t : __with_default_get_env<upon_stopped_t>
 {
-    template <class _Sender, class _Fun>
-    using __sender = __t<__sender<__id<__decay_t<_Sender>>, _Fun>>;
-
     template <sender _Sender, __movable_value _Fun>
-        requires __tag_invocable_with_completion_scheduler<
-                     upon_stopped_t, set_stopped_t, _Sender, _Fun> &&
-                 __callable<_Fun>
-    sender auto operator()(_Sender&& __sndr, _Fun __fun) const noexcept(
-        nothrow_tag_invocable<
-            upon_stopped_t, __completion_scheduler_for<_Sender, set_stopped_t>,
-            _Sender, _Fun>)
+        requires __callable<_Fun>
+    auto operator()(_Sender&& __sndr, _Fun __fun) const
     {
-        auto __sched = get_completion_scheduler<set_stopped_t>(
-            get_env(__sndr)); // TODO ADD TEST!
-        return tag_invoke(upon_stopped_t{}, std::move(__sched),
-                          (_Sender&&)__sndr, (_Fun&&)__fun);
+        auto __domain = __get_early_domain(__sndr);
+        return stdexec::transform_sender(
+            __domain,
+            __make_sexpr<upon_stopped_t>((_Fun&&)__fun, (_Sender&&)__sndr));
     }
 
-    template <sender _Sender, __movable_value _Fun>
-        requires(!__tag_invocable_with_completion_scheduler<
-                    upon_stopped_t, set_stopped_t, _Sender, _Fun>) &&
-                tag_invocable<upon_stopped_t, _Sender, _Fun> && __callable<_Fun>
-    sender auto operator()(_Sender&& __sndr, _Fun __fun) const
-        noexcept(nothrow_tag_invocable<upon_stopped_t, _Sender, _Fun>)
-    {
-        return tag_invoke(upon_stopped_t{}, (_Sender&&)__sndr, (_Fun&&)__fun);
-    }
-
-    template <sender _Sender, __movable_value _Fun>
-        requires(!__tag_invocable_with_completion_scheduler<
-                    upon_stopped_t, set_stopped_t, _Sender, _Fun>) &&
-                (!tag_invocable<upon_stopped_t, _Sender, _Fun>) &&
-                __callable<_Fun> && sender<__sender<_Sender, _Fun>>
-    __sender<_Sender, _Fun> operator()(_Sender&& __sndr, _Fun __fun) const
-    {
-        return __sender<_Sender, _Fun>{(_Sender&&)__sndr, (_Fun&&)__fun};
-    }
-
-    template <__callable _Fun>
-    __binder_back<upon_stopped_t, _Fun> operator()(_Fun __fun) const
+    template <__movable_value _Fun>
+        requires __callable<_Fun>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+        __binder_back<upon_stopped_t, _Fun>
+        operator()(_Fun __fun) const
     {
         return {{}, {}, {(_Fun&&)__fun}};
     }
+
+    using _Sender = __1;
+    using _Fun = __0;
+    using __legacy_customizations_t =
+        __types<tag_invoke_t(upon_stopped_t,
+                             get_completion_scheduler_t<set_value_t>(
+                                 get_env_t(_Sender&)),
+                             _Sender, _Fun),
+                tag_invoke_t(upon_stopped_t, _Sender, _Fun)>;
+
+#if STDEXEC_FRIENDSHIP_IS_LEXICAL()
+  private:
+    template <class...>
+    friend struct stdexec::__sexpr;
+#endif
+
+    template <sender_expr_for<upon_stopped_t> _Sender, class _Env>
+    static auto get_completion_signatures(_Sender&&, _Env&&)
+        -> __completion_signatures_t<__decay_t<__data_of<_Sender>>,
+                                     __child_of<_Sender>, _Env>
+    {
+        return {};
+    }
+
+    template <sender_expr_for<upon_stopped_t> _Sender, receiver _Receiver>
+    static auto connect(_Sender&& __sndr, _Receiver __rcvr) noexcept(
+        __nothrow_callable<__sexpr_apply_t, _Sender, __connect_fn<_Receiver>>)
+        -> __call_result_t<__sexpr_apply_t, _Sender, __connect_fn<_Receiver>>
+    {
+        return __sexpr_apply((_Sender&&)__sndr,
+                             __connect_fn<_Receiver>{__rcvr});
+    }
 };
 } // namespace __upon_stopped
 
@@ -3804,177 +4400,223 @@
     "In stdexec::bulk(Sender, Shape, Function)..."__csz;
 using __on_not_callable = __callable_error<__bulk_context>;
 
-template <class _ReceiverId, integral _Shape, class _Fun>
+template <class _Shape, class _Fun>
+struct __data
+{
+    _Shape __shape_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Fun __fun_;
+    static constexpr auto __mbrs_ =
+        __mliterals<&__data::__shape_, &__data::__fun_>();
+};
+template <class _Shape, class _Fun>
+__data(_Shape, _Fun) -> __data<_Shape, _Fun>;
+
+template <class _ReceiverId, class _Shape, class _Fun>
 struct __receiver
 {
     using _Receiver = stdexec::__t<_ReceiverId>;
 
-    class __t : receiver_adaptor<__t, _Receiver>
+    struct __op_state : __data<_Shape, _Fun>
     {
-        friend receiver_adaptor<__t, _Receiver>;
+        STDEXEC_ATTRIBUTE((no_unique_address)) _Receiver __rcvr_;
+    };
 
-        STDEXEC_NO_UNIQUE_ADDRESS _Shape __shape_;
-        STDEXEC_NO_UNIQUE_ADDRESS _Fun __f_;
+    struct __t
+    {
+        using is_receiver = void;
+        using __id = __receiver;
+        __op_state* __op_;
 
-        template <class... _As>
-        void set_value(_As&&... __as) && noexcept
+        template <same_as<set_value_t> _Tag, class... _As>
+            requires __callable<_Tag, _Receiver, _As...>
+        friend void tag_invoke(_Tag, __t&& __self, _As&&... __as) noexcept
             requires __nothrow_callable<_Fun, _Shape, _As&...>
         {
-            for (_Shape __i{}; __i != __shape_; ++__i)
+            for (_Shape __i{}; __i != __self.__op_->__shape_; ++__i)
             {
-                __f_(__i, __as...);
+                __self.__op_->__fun_(__i, __as...);
             }
-            stdexec::set_value(std::move(this->base()), (_As&&)__as...);
+            stdexec::set_value((_Receiver&&)__self.__op_->__rcvr_,
+                               (_As&&)__as...);
         }
 
-        template <class... _As>
-        void set_value(_As&&... __as) && noexcept
+        template <same_as<set_value_t> _Tag, class... _As>
+            requires __callable<_Tag, _Receiver, _As...>
+        friend void tag_invoke(_Tag, __t&& __self, _As&&... __as) noexcept
             requires __callable<_Fun, _Shape, _As&...>
         {
             try
             {
-                for (_Shape __i{}; __i != __shape_; ++__i)
+                for (_Shape __i{}; __i != __self.__op_->__shape_; ++__i)
                 {
-                    __f_(__i, __as...);
+                    __self.__op_->__fun_(__i, __as...);
                 }
-                stdexec::set_value(std::move(this->base()), (_As&&)__as...);
+                stdexec::set_value((_Receiver&&)__self.__op_->__rcvr_,
+                                   (_As&&)__as...);
             }
             catch (...)
             {
-                stdexec::set_error(std::move(this->base()),
+                stdexec::set_error((_Receiver&&)__self.__op_->__rcvr_,
                                    std::current_exception());
             }
         }
 
-      public:
-        using __id = __receiver;
+        template <same_as<set_error_t> _Tag, class _Error>
+            requires __callable<_Tag, _Receiver, _Error>
+        friend void tag_invoke(_Tag, __t&& __self, _Error&& __error) noexcept
+        {
+            stdexec::set_error((_Receiver&&)__self.__op_->__rcvr_,
+                               (_Error&&)__error);
+        }
 
-        explicit __t(_Receiver __rcvr, _Shape __shape, _Fun __fun) :
-            receiver_adaptor<__t, _Receiver>((_Receiver&&)__rcvr),
-            __shape_(__shape), __f_((_Fun&&)__fun)
+        template <same_as<set_stopped_t> _Tag>
+            requires __callable<_Tag, _Receiver>
+        friend void tag_invoke(_Tag, __t&& __self) noexcept
+        {
+            stdexec::set_stopped((_Receiver&&)__self.__op_->__rcvr_);
+        }
+
+        friend env_of_t<_Receiver> tag_invoke(get_env_t,
+                                              const __t& __self) noexcept
+        {
+            return stdexec::get_env(__self.__op_->__rcvr_);
+        }
+    };
+};
+
+template <class _CvrefSenderId, class _ReceiverId, class _Shape, class _Fun>
+struct __operation
+{
+    using _CvrefSender = stdexec::__cvref_t<_CvrefSenderId>;
+    using _Receiver = stdexec::__t<_ReceiverId>;
+    using __receiver_id = __receiver<_ReceiverId, _Shape, _Fun>;
+    using __receiver_t = stdexec::__t<__receiver_id>;
+
+    struct __t : __immovable
+    {
+        using __id = __operation;
+        using __data_t = __data<_Shape, _Fun>;
+
+        typename __receiver_id::__op_state __state_;
+        connect_result_t<_CvrefSender, __receiver_t> __op_;
+
+        __t(_CvrefSender&& __sndr, _Receiver __rcvr, __data_t __data) //
+            noexcept(__nothrow_decay_copyable<_Receiver>              //
+                     && __nothrow_decay_copyable<__data_t>            //
+                     && __nothrow_connectable<_CvrefSender, __receiver_t>) :
+            __state_{(__data_t&&)__data, (_Receiver&&)__rcvr},
+            __op_(connect((_CvrefSender&&)__sndr, __receiver_t{&__state_}))
         {}
+
+        friend void tag_invoke(start_t, __t& __self) noexcept
+        {
+            start(__self.__op_);
+        }
     };
 };
 
 template <class _Ty>
 using __decay_ref = __decay_t<_Ty>&;
 
-template <class _SenderId, integral _Shape, class _Fun>
-struct __sender
-{
-    using _Sender = stdexec::__t<_SenderId>;
-
-    template <receiver _Receiver>
-    using __receiver =
-        stdexec::__t<__receiver<stdexec::__id<_Receiver>, _Shape, _Fun>>;
-
-    struct __t
-    {
-        using __id = __sender;
-        using is_sender = void;
-
-        STDEXEC_NO_UNIQUE_ADDRESS _Sender __sndr_;
-        STDEXEC_NO_UNIQUE_ADDRESS _Shape __shape_;
-        STDEXEC_NO_UNIQUE_ADDRESS _Fun __fun_;
-
-        template <class _Sender, class _Env, class _Catch>
-        using __with_error_invoke_t = //
-            __if<__try_value_types_of_t<
-                     _Sender, _Env,
-                     __transform<
-                         __q<__decay_ref>,
+template <class _CvrefSender, class _Env, class _Shape, class _Fun,
+          class _Catch>
+using __with_error_invoke_t = //
+    __if<__try_value_types_of_t<
+             _CvrefSender, _Env,
+             __transform<__q<__decay_ref>,
                          __mbind_front<__mtry_catch_q<__non_throwing_, _Catch>,
                                        _Fun, _Shape>>,
-                     __q<__mand>>,
-                 completion_signatures<>, __with_exception_ptr>;
+             __q<__mand>>,
+         completion_signatures<>, __with_exception_ptr>;
 
-        template <class _Self, class _Env>
-        using __completion_signatures = //
-            __try_make_completion_signatures<
-                __copy_cvref_t<_Self, _Sender>, _Env,
-                __with_error_invoke_t<__copy_cvref_t<_Self, _Sender>, _Env,
-                                      __on_not_callable>>;
+template <class _CvrefSender, class _Env, class _Shape, class _Fun>
+using __completion_signatures = //
+    __try_make_completion_signatures<
+        _CvrefSender, _Env,
+        __with_error_invoke_t<_CvrefSender, _Env, _Shape, _Fun,
+                              __on_not_callable>>;
 
-        template <__decays_to<__t> _Self, receiver _Receiver>
-            requires sender_to<__copy_cvref_t<_Self, _Sender>,
-                               __receiver<_Receiver>>
-        friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr) //
-            noexcept(__nothrow_connectable<__copy_cvref_t<_Self, _Sender>,
-                                           __receiver<_Receiver>>)
-                -> connect_result_t<__copy_cvref_t<_Self, _Sender>,
-                                    __receiver<_Receiver>>
-        {
-            return stdexec::connect(
-                ((_Self&&)__self).__sndr_,
-                __receiver<_Receiver>{(_Receiver&&)__rcvr, __self.__shape_,
-                                      ((_Self&&)__self).__fun_});
-        }
+template <class _Receiver>
+struct __connect_fn
+{
+    _Receiver& __rcvr_;
 
-        template <__decays_to<__t> _Self, class _Env>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
-            -> dependent_completion_signatures<_Env>;
+    template <class _Child, class _Data>
+    using __operation_t = //
+        __t<__operation<__cvref_id<_Child>, __id<_Receiver>,
+                        decltype(_Data::__shape_), decltype(_Data::__fun_)>>;
 
-        template <__decays_to<__t> _Self, class _Env>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
-            -> __completion_signatures<_Self, _Env>
-            requires true;
-
-        friend auto tag_invoke(get_env_t, const __t& __self) noexcept
-            -> env_of_t<const _Sender&>
-        {
-            return get_env(__self.__sndr_);
-        }
-    };
+    template <class _Data, class _Child>
+    auto operator()(__ignore, _Data __data, _Child&& __child) const
+        noexcept(__nothrow_constructible_from<__operation_t<_Child, _Data>,
+                                              _Child, _Receiver, _Data>)
+            -> __operation_t<_Child, _Data>
+    {
+        return __operation_t<_Child, _Data>{
+            (_Child&&)__child, (_Receiver&&)__rcvr_, (_Data&&)__data};
+    }
 };
 
-struct bulk_t
+struct bulk_t : __with_default_get_env<bulk_t>
 {
-    template <sender _Sender, integral _Shape, class _Fun>
-    using __sender =
-        __t<__sender<stdexec::__id<__decay_t<_Sender>>, _Shape, _Fun>>;
-
     template <sender _Sender, integral _Shape, __movable_value _Fun>
-        requires __tag_invocable_with_completion_scheduler<
-            bulk_t, set_value_t, _Sender, _Shape, _Fun>
-    sender auto operator()(_Sender&& __sndr, _Shape __shape, _Fun __fun) const
-        noexcept(nothrow_tag_invocable<
-                 bulk_t, __completion_scheduler_for<_Sender, set_value_t>,
-                 _Sender, _Shape, _Fun>)
+    STDEXEC_ATTRIBUTE((host, device))
+    auto operator()(_Sender&& __sndr, _Shape __shape, _Fun __fun) const
     {
-        auto __sched = get_completion_scheduler<set_value_t>(get_env(__sndr));
-        return tag_invoke(bulk_t{}, std::move(__sched), (_Sender&&)__sndr,
-                          (_Shape&&)__shape, (_Fun&&)__fun);
-    }
-
-    template <sender _Sender, integral _Shape, __movable_value _Fun>
-        requires(!__tag_invocable_with_completion_scheduler<
-                    bulk_t, set_value_t, _Sender, _Shape, _Fun>) &&
-                tag_invocable<bulk_t, _Sender, _Shape, _Fun>
-    sender auto operator()(_Sender&& __sndr, _Shape __shape, _Fun __fun) const
-        noexcept(nothrow_tag_invocable<bulk_t, _Sender, _Shape, _Fun>)
-    {
-        return tag_invoke(bulk_t{}, (_Sender&&)__sndr, (_Shape&&)__shape,
-                          (_Fun&&)__fun);
-    }
-
-    template <sender _Sender, integral _Shape, __movable_value _Fun>
-        requires(!__tag_invocable_with_completion_scheduler<
-                    bulk_t, set_value_t, _Sender, _Shape, _Fun>) &&
-                (!tag_invocable<bulk_t, _Sender, _Shape, _Fun>)
-    STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
-        __sender<_Sender, _Shape, _Fun>
-        operator()(_Sender&& __sndr, _Shape __shape, _Fun __fun) const
-    {
-        return __sender<_Sender, _Shape, _Fun>{(_Sender&&)__sndr, __shape,
-                                               (_Fun&&)__fun};
+        auto __domain = __get_early_domain(__sndr);
+        return stdexec::transform_sender(
+            __domain, __make_sexpr<bulk_t>(__data{__shape, (_Fun&&)__fun},
+                                           (_Sender&&)__sndr));
     }
 
     template <integral _Shape, class _Fun>
+    STDEXEC_ATTRIBUTE((always_inline)) //
     __binder_back<bulk_t, _Shape, _Fun> operator()(_Shape __shape,
                                                    _Fun __fun) const
     {
         return {{}, {}, {(_Shape&&)__shape, (_Fun&&)__fun}};
     }
+
+    // This describes how to use the pieces of a bulk sender to find
+    // legacy customizations of the bulk algorithm.
+    using _Sender = __1;
+    using _Shape = __nth_member<0>(__0);
+    using _Fun = __nth_member<1>(__0);
+    using __legacy_customizations_t =
+        __types<tag_invoke_t(bulk_t,
+                             get_completion_scheduler_t<set_value_t>(
+                                 get_env_t(_Sender&)),
+                             _Sender, _Shape, _Fun),
+                tag_invoke_t(bulk_t, _Sender, _Shape, _Fun)>;
+
+#if STDEXEC_FRIENDSHIP_IS_LEXICAL()
+  private:
+    template <class...>
+    friend struct stdexec::__sexpr;
+#endif
+
+    template <class _Sender>
+    using __fun_t = decltype(__decay_t<__data_of<_Sender>>::__fun_);
+
+    template <class _Sender>
+    using __shape_t = decltype(__decay_t<__data_of<_Sender>>::__shape_);
+
+    template <sender_expr_for<bulk_t> _Sender, class _Env>
+    static auto get_completion_signatures(_Sender&&, _Env&&)
+        -> __completion_signatures<__child_of<_Sender>, _Env,
+                                   __shape_t<_Sender>, __fun_t<_Sender>>
+    {
+        return {};
+    }
+
+    template <sender_expr_for<bulk_t> _Sender, receiver _Receiver>
+    static auto connect(_Sender&& __sndr, _Receiver __rcvr) noexcept(
+        __nothrow_callable<__sexpr_apply_t, _Sender, __connect_fn<_Receiver>>)
+        -> __call_result_t<__sexpr_apply_t, _Sender, __connect_fn<_Receiver>>
+    {
+        return __sexpr_apply((_Sender&&)__sndr,
+                             __connect_fn<_Receiver>{__rcvr});
+    }
 };
 } // namespace __bulk
 
@@ -4050,7 +4692,7 @@
     __notify_fn* __notify_{};
 };
 
-template <class _CvrefSenderId, class _EnvId>
+template <class _CvrefSenderId, class _EnvId = __id<empty_env>>
 struct __sh_state
 {
     using _CvrefSender = stdexec::__cvref_t<_CvrefSenderId>;
@@ -4081,17 +4723,16 @@
 
         using __receiver_ = stdexec::__t<__receiver<_CvrefSenderId, _EnvId>>;
 
-        void* const __token_{(void*)0xDEADBEEF};
         in_place_stop_source __stop_source_{};
         __variant_t __data_;
         std::atomic<void*> __head_{nullptr};
         __env_t<_Env> __env_;
         connect_result_t<_CvrefSender, __receiver_> __op_state2_;
 
-        explicit __t(_CvrefSender&& __sndr, _Env __env) :
+        explicit __t(_CvrefSender&& __sndr, _Env __env = {}) :
             __env_(
-                __make_env((_Env&&)__env, __with_(get_stop_token,
-                                                  __stop_source_.get_token()))),
+                __make_env((_Env&&)__env, __mkprop(__stop_source_.get_token(),
+                                                   get_stop_token))),
             __op_state2_(connect((_CvrefSender&&)__sndr, __receiver_{*this}))
         {}
 
@@ -4114,6 +4755,8 @@
 };
 
 template <class _CvrefSenderId, class _EnvId, class _ReceiverId>
+    requires sender_to<__cvref_t<_CvrefSenderId>,
+                       __t<__receiver<_CvrefSenderId, _EnvId>>>
 struct __operation
 {
     using _CvrefSender = stdexec::__cvref_t<_CvrefSenderId>;
@@ -4163,7 +4806,7 @@
 
             std::visit(
                 [&](const auto& __tupl) noexcept -> void {
-                std::apply(
+                __apply(
                     [&](auto __tag, const auto&... __args) noexcept -> void {
                     __tag((_Receiver&&)__op->__rcvr_, __args...);
                 },
@@ -4176,7 +4819,6 @@
         {
             stdexec::__t<__sh_state<_CvrefSenderId, _EnvId>>* __shared_state =
                 __self.__shared_state_.get();
-            STDEXEC_ASSERT(__shared_state->__token_ == (void*)0xDEADBEEF);
             std::atomic<void*>& __head = __shared_state->__head_;
             void* const __completion_state = static_cast<void*>(__shared_state);
             void* __old = __head.load(std::memory_order_acquire);
@@ -4219,117 +4861,117 @@
     };
 };
 
-template <class _CvrefSenderId, class _EnvId>
-struct __sender
+struct __split_t
 {
-    using _CvrefSender = stdexec::__cvref_t<_CvrefSenderId>;
-    using _Env = stdexec::__t<_EnvId>;
+#if STDEXEC_FRIENDSHIP_IS_LEXICAL()
+  private:
+    template <class...>
+    friend struct stdexec::__sexpr;
+#endif
 
-    template <class _Receiver>
-    using __operation = stdexec::__t<
-        __operation<_CvrefSenderId, _EnvId, stdexec::__id<_Receiver>>>;
+    template <class... _Tys>
+    using __set_value_t =
+        completion_signatures<set_value_t(const __decay_t<_Tys>&...)>;
 
-    struct __t
-    {
-        using __id = __sender;
-        using is_sender = void;
+    template <class _Ty>
+    using __set_error_t =
+        completion_signatures<set_error_t(const __decay_t<_Ty>&)>;
 
-        explicit __t(_CvrefSender&& __sndr, _Env __env) :
-            __shared_state_{std::make_shared<__sh_state_>(
-                static_cast<_CvrefSender&&>(__sndr), (_Env&&)__env)}
-        {}
+    template <class _CvrefSenderId, class _EnvId>
+    using __completions_t = //
+        __try_make_completion_signatures<
+            // NOT TO SPEC:
+            // See
+            // https://github.com/brycelelbach/wg21_p2300_execution/issues/26
+            __cvref_t<_CvrefSenderId>, __env_t<__t<_EnvId>>,
+            completion_signatures<set_error_t(const std::exception_ptr&),
+                                  set_stopped_t()>, // NOT TO SPEC
+            __q<__set_value_t>, __q<__set_error_t>>;
 
-      private:
-        using __sh_state_ = stdexec::__t<__sh_state<_CvrefSenderId, _EnvId>>;
-
-        template <class... _Tys>
-        using __set_value_t =
-            completion_signatures<set_value_t(const __decay_t<_Tys>&...)>;
-
-        template <class _Ty>
-        using __set_error_t =
-            completion_signatures<set_error_t(const __decay_t<_Ty>&)>;
-
-        template <class _Self>
-        using __completions_t = //
-            __try_make_completion_signatures<
-                // NOT TO SPEC:
-                // See
-                // https://github.com/brycelelbach/wg21_p2300_execution/issues/26
-                _CvrefSender, __env_t<__mfront<_Env, _Self>>,
-                completion_signatures<set_error_t(const std::exception_ptr&),
-                                      set_stopped_t()>, // NOT TO SPEC
-                __q<__set_value_t>, __q<__set_error_t>>;
-
-        std::shared_ptr<__sh_state_> __shared_state_;
-
-        template <__decays_to<__t> _Self,
-                  receiver_of<__completions_t<_Self>> _Receiver>
-        friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __recvr) //
-            noexcept(std::is_nothrow_move_constructible_v<_Receiver>)
-                -> __operation<_Receiver>
-        {
-            return __operation<_Receiver>{(_Receiver&&)__recvr,
-                                          __self.__shared_state_};
-        }
-
-        template <__decays_to<__t> _Self, class _OtherEnv>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&,
-                               _OtherEnv&&) -> __completions_t<_Self>;
+    static inline constexpr auto __connect_fn =
+        []<class _Receiver>(_Receiver& __rcvr) noexcept {
+        return
+            [&]<class _ShState>(auto, std::shared_ptr<_ShState> __sh_state) //
+            noexcept(__nothrow_decay_copyable<_Receiver>)
+                -> __t<__mapply<__mbind_back_q<__operation, __id<_Receiver>>,
+                                __id<_ShState>>> {
+            return {(_Receiver&&)__rcvr, std::move(__sh_state)};
+        };
     };
-};
 
-struct split_t;
+    static inline constexpr auto __get_completion_signatures_fn =
+        []<class _ShState>(auto, const std::shared_ptr<_ShState>&) //
+        -> __mapply<__q<__completions_t>, __id<_ShState>> { return {}; };
 
-// When looking for user-defined customizations of split, these
-// are the signatures to test against, in order:
-using _Sender = __0;
-using _Env = __1;
-using __cust_sigs = //
-    __types<tag_invoke_t(split_t,
-                         get_completion_scheduler_t<set_value_t>(
-                             get_env_t(const _Sender&)),
-                         _Sender),
-            tag_invoke_t(split_t,
-                         get_completion_scheduler_t<set_value_t>(
-                             get_env_t(const _Sender&)),
-                         _Sender, _Env),
-            tag_invoke_t(split_t, get_scheduler_t(_Env&), _Sender),
-            tag_invoke_t(split_t, get_scheduler_t(_Env&), _Sender, _Env),
-            tag_invoke_t(split_t, _Sender),
-            tag_invoke_t(split_t, _Sender, _Env)>;
-
-template <class _Sender, class _Env>
-inline constexpr bool __is_split_customized =
-    __minvocable<__which<__cust_sigs>, _Sender, _Env>;
-
-template <class _Sender, class _Env>
-using __sender_t =
-    __t<__sender<stdexec::__cvref_id<_Sender>, stdexec::__id<__decay_t<_Env>>>>;
-
-template <class _Sender, class _Env>
-using __dispatcher_for =
-    __make_dispatcher<__cust_sigs, __mconstructor_for<__sender_t>, _Sender,
-                      _Env>;
-
-struct split_t
-{
-    template <sender _Sender, class _Env = empty_env>
-        requires(sender_in<_Sender, _Env> &&
-                 __decay_copyable<env_of_t<_Sender>>) ||
-                __is_split_customized<_Sender, _Env>
-    auto operator()(_Sender&& __sndr, _Env&& __env = _Env{}) const noexcept(
-        __nothrow_callable<__dispatcher_for<_Sender, _Env>, _Sender, _Env>)
-        -> __call_result_t<__dispatcher_for<_Sender, _Env>, _Sender, _Env>
+    template <sender_expr_for<__split_t> _Self, class _Receiver>
+    static auto connect(_Self&& __self, _Receiver __rcvr) noexcept(
+        __nothrow_callable<
+            __sexpr_apply_t, _Self,
+            __call_result_t<__mtypeof<__connect_fn>, _Receiver&>>)
+        -> __call_result_t<__sexpr_apply_t, _Self,
+                           __call_result_t<__mtypeof<__connect_fn>, _Receiver&>>
     {
-        return __dispatcher_for<_Sender, _Env>{}((_Sender&&)__sndr,
-                                                 (_Env&&)__env);
+        return __sexpr_apply((_Self&&)__self, __connect_fn(__rcvr));
     }
 
+    template <sender_expr_for<__split_t> _Self, class _OtherEnv>
+    static auto get_completion_signatures(_Self&&, _OtherEnv&&)
+        -> __call_result_t<__sexpr_apply_t, _Self,
+                           __mtypeof<__get_completion_signatures_fn>>
+    {
+        return {};
+    }
+};
+
+struct split_t : __split_t
+{
+    template <sender _Sender>
+        requires sender_in<_Sender, empty_env> &&
+                 __decay_copyable<env_of_t<_Sender>>
+    auto operator()(_Sender&& __sndr) const
+    {
+        auto __domain = __get_early_domain(__sndr);
+        return stdexec::transform_sender(
+            __domain, __make_sexpr<split_t>(__(), (_Sender&&)__sndr));
+    }
+
+    template <sender _Sender, class _Env>
+        requires sender_in<_Sender, _Env> && __decay_copyable<env_of_t<_Sender>>
+    auto operator()(_Sender&& __sndr, _Env&& __env) const
+    {
+        auto __domain = __get_late_domain(__sndr, __env);
+        return stdexec::transform_sender(
+            __domain, __make_sexpr<split_t>(__(), (_Sender&&)__sndr),
+            (_Env&&)__env);
+    }
+
+    STDEXEC_ATTRIBUTE((always_inline)) //
     __binder_back<split_t> operator()() const
     {
         return {{}, {}, {}};
     }
+
+    using _Sender = __1;
+    using __legacy_customizations_t = //
+        __types<tag_invoke_t(split_t,
+                             get_completion_scheduler_t<set_value_t>(
+                                 get_env_t(const _Sender&)),
+                             _Sender),
+                tag_invoke_t(split_t, _Sender)>;
+
+    template <class _Sender, class... _Env>
+    static auto transform_sender(_Sender&& __sndr, _Env... __env)
+    {
+        return __sexpr_apply(
+            (_Sender&&)__sndr,
+            [&]<class _Child>(__ignore, __ignore, _Child&& __child) {
+            using __sh_state_t =
+                __t<__sh_state<__cvref_id<_Child>, __id<_Env>...>>;
+            auto __sh_state = std::make_shared<__sh_state_t>(
+                (_Child&&)__child, std::move(__env)...);
+            return __make_sexpr<__split_t>(std::move(__sh_state));
+        });
+    }
 };
 } // namespace __split
 
@@ -4348,7 +4990,7 @@
 template <class _CvrefSenderId, class _EnvId>
 struct __sh_state;
 
-template <class _CvrefSenderId, class _EnvId>
+template <class _CvrefSenderId, class _EnvId = __id<empty_env>>
 struct __receiver
 {
     using _CvrefSender = stdexec::__cvref_t<_CvrefSenderId>;
@@ -4406,7 +5048,7 @@
     __notify_fn* __notify_{};
 };
 
-template <class _CvrefSenderId, class _EnvId>
+template <class _CvrefSenderId, class _EnvId = __id<empty_env>>
 struct __sh_state
 {
     using _CvrefSender = stdexec::__cvref_t<_CvrefSenderId>;
@@ -4444,10 +5086,10 @@
         __env_t<_Env> __env_;
         connect_result_t<_CvrefSender, __receiver_t> __op_state2_;
 
-        explicit __t(_CvrefSender&& __sndr, _Env __env) :
+        explicit __t(_CvrefSender&& __sndr, _Env __env = {}) :
             __env_(
-                __make_env((_Env&&)__env, __with_(get_stop_token,
-                                                  __stop_source_.get_token()))),
+                __make_env((_Env&&)__env, __mkprop(__stop_source_.get_token(),
+                                                   get_stop_token))),
             __op_state2_(connect((_CvrefSender&&)__sndr, __receiver_t{*this}))
         {
             start(__op_state2_);
@@ -4533,7 +5175,7 @@
 
             std::visit(
                 [&](auto& __tupl) noexcept -> void {
-                std::apply(
+                __apply(
                     [&](auto __tag, auto&... __args) noexcept -> void {
                     __tag((_Receiver&&)__op->__rcvr_, std::move(__args)...);
                 },
@@ -4587,141 +5229,209 @@
     };
 };
 
-template <class _CvrefSenderId, class _EnvId>
-struct __sender
+template <class _ShState>
+struct __data
 {
-    using _CvrefSender = stdexec::__cvref_t<_CvrefSenderId>;
-    using _Env = stdexec::__t<_EnvId>;
+    __data(__intrusive_ptr<_ShState> __sh_state) noexcept :
+        __sh_state_(std::move(__sh_state))
+    {}
 
-    struct __t
+    __data(__data&&) = default;
+    __data& operator=(__data&&) = default;
+
+    ~__data()
     {
-        using __id = __sender;
-        using is_sender = void;
-
-        explicit __t(_CvrefSender __sndr, _Env __env) :
-            __shared_state_{__make_intrusive<__sh_state_>(
-                (_CvrefSender&&)__sndr, (_Env&&)__env)}
-        {}
-
-        ~__t()
+        if (__sh_state_ != nullptr)
         {
-            if (nullptr != __shared_state_)
-            {
-                // We're detaching a potentially running operation. Request
-                // cancellation.
-                __shared_state_->__detach(); // BUGBUG NOT TO SPEC
-            }
+            // detach from the still-running operation.
+            // NOT TO SPEC: This also requests cancellation.
+            __sh_state_->__detach();
         }
-
-        // Move-only:
-        __t(__t&&) = default;
-
-      private:
-        using __sh_state_ = stdexec::__t<__sh_state<_CvrefSenderId, _EnvId>>;
-        template <class _Receiver>
-        using __operation = stdexec::__t<
-            __operation<_CvrefSenderId, _EnvId, stdexec::__id<_Receiver>>>;
-
-        template <class... _Tys>
-        using __set_value_t =
-            completion_signatures<set_value_t(__decay_t<_Tys>&&...)>;
-
-        template <class _Ty>
-        using __set_error_t =
-            completion_signatures<set_error_t(__decay_t<_Ty>&&)>;
-
-        template <class _Self>
-        using __completions_t = //
-            __try_make_completion_signatures<
-                _CvrefSender, __env_t<__mfront<_Env, _Self>>,
-                completion_signatures<set_error_t(std::exception_ptr&&),
-                                      set_stopped_t()>, // BUGBUG NOT TO SPEC
-                __q<__set_value_t>, __q<__set_error_t>>;
-
-        __intrusive_ptr<__sh_state_> __shared_state_;
-
-        template <same_as<__t> _Self,
-                  receiver_of<__completions_t<_Self>> _Receiver>
-        friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr) //
-            noexcept(std::is_nothrow_move_constructible_v<_Receiver>)
-                -> __operation<_Receiver>
-        {
-            return __operation<_Receiver>{(_Receiver&&)__rcvr,
-                                          std::move(__self).__shared_state_};
-        }
-
-        template <same_as<__t> _Self, class _OtherEnv>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&,
-                               _OtherEnv&&) -> __completions_t<_Self>;
-    };
-};
-
-struct ensure_started_t;
-
-// When looking for user-defined customizations of ensure_started, these
-// are the signatures to test against, in order:
-using _CvrefSender = __0;
-using _Env = __1;
-using __cust_sigs = //
-    __types<tag_invoke_t(ensure_started_t,
-                         get_completion_scheduler_t<set_value_t>(
-                             get_env_t(const _CvrefSender&)),
-                         _CvrefSender),
-            tag_invoke_t(ensure_started_t,
-                         get_completion_scheduler_t<set_value_t>(
-                             get_env_t(const _CvrefSender&)),
-                         _CvrefSender, _Env),
-            tag_invoke_t(ensure_started_t, get_scheduler_t(_Env&),
-                         _CvrefSender),
-            tag_invoke_t(ensure_started_t, get_scheduler_t(_Env&), _CvrefSender,
-                         _Env),
-            tag_invoke_t(ensure_started_t, _CvrefSender),
-            tag_invoke_t(ensure_started_t, _CvrefSender, _Env)>;
-
-template <class _CvrefSender, class _Env>
-inline constexpr bool __is_ensure_started_customized =
-    __minvocable<__which<__cust_sigs>, _CvrefSender, _Env>;
-
-template <class _Sender, class _Env>
-using __sender_t = __t<__sender<stdexec::__cvref_id<_Sender, _Sender>,
-                                stdexec::__id<__decay_t<_Env>>>>;
-
-template <class _Sender>
-concept __ensure_started_sender = //
-    __is_instance_of<__id<__decay_t<_Sender>>, __sender>;
-
-template <class _Sender>
-using __fallback = __if_c<__ensure_started_sender<_Sender>, __mconst<__first>,
-                          __mconstructor_for<__sender_t>>;
-
-template <class _Sender, class _Env>
-using __dispatcher_for =
-    __make_dispatcher<__cust_sigs, __fallback<_Sender>, _Sender, _Env>;
-
-struct ensure_started_t
-{
-    template <sender _Sender, class _Env = empty_env>
-        requires(sender_in<_Sender, _Env> &&
-                 __decay_copyable<env_of_t<_Sender>>) ||
-                __is_ensure_started_customized<_Sender, _Env>
-    auto operator()(_Sender&& __sndr, _Env&& __env = _Env{}) const noexcept(
-        __nothrow_callable<__dispatcher_for<_Sender, _Env>, _Sender, _Env>)
-        -> __call_result_t<__dispatcher_for<_Sender, _Env>, _Sender, _Env>
-    {
-        return __dispatcher_for<_Sender, _Env>{}((_Sender&&)__sndr,
-                                                 (_Env&&)__env);
     }
 
+    __intrusive_ptr<_ShState> __sh_state_;
+};
+
+struct __ensure_started_t
+{
+#if STDEXEC_FRIENDSHIP_IS_LEXICAL()
+  private:
+    template <class...>
+    friend struct stdexec::__sexpr;
+    friend struct ensure_started_t;
+#endif
+
+    template <class... _Tys>
+    using __set_value_t =
+        completion_signatures<set_value_t(__decay_t<_Tys>&&...)>;
+
+    template <class _Ty>
+    using __set_error_t = completion_signatures<set_error_t(__decay_t<_Ty>&&)>;
+
+    template <class _CvrefSenderId, class _EnvId>
+    using __completions_t = //
+        __try_make_completion_signatures<
+            // NOT TO SPEC:
+            // See
+            // https://github.com/brycelelbach/wg21_p2300_execution/issues/26
+            __cvref_t<_CvrefSenderId>, __env_t<__t<_EnvId>>,
+            completion_signatures<set_error_t(std::exception_ptr&&),
+                                  set_stopped_t()>, // NOT TO SPEC
+            __q<__set_value_t>, __q<__set_error_t>>;
+
+    static inline constexpr auto __connect_fn =
+        []<class _Receiver>(_Receiver& __rcvr) noexcept {
+        return [&]<class _ShState>(auto, __data<_ShState> __dat) //
+               noexcept(__nothrow_decay_copyable<_Receiver>)
+                   -> __t<__mapply<__mbind_back_q<__operation, __id<_Receiver>>,
+                                   __id<_ShState>>> {
+            return {(_Receiver&&)__rcvr, std::move(__dat.__sh_state_)};
+        };
+    };
+
+    static inline constexpr auto __get_completion_signatures_fn =
+        []<class _ShState>(auto, const __data<_ShState>&) //
+        -> __mapply<__q<__completions_t>, __id<_ShState>> { return {}; };
+
+    template <sender_expr_for<__ensure_started_t> _Self, class _Receiver>
+    static auto connect(_Self&& __self, _Receiver __rcvr) noexcept(
+        __nothrow_callable<
+            __sexpr_apply_t, _Self,
+            __call_result_t<__mtypeof<__connect_fn>, _Receiver&>>)
+        -> __call_result_t<__sexpr_apply_t, _Self,
+                           __call_result_t<__mtypeof<__connect_fn>, _Receiver&>>
+    {
+        return __sexpr_apply((_Self&&)__self, __connect_fn(__rcvr));
+    }
+
+    template <sender_expr_for<__ensure_started_t> _Self, class _OtherEnv>
+    static auto get_completion_signatures(_Self&&, _OtherEnv&&)
+        -> __call_result_t<__sexpr_apply_t, _Self,
+                           __mtypeof<__get_completion_signatures_fn>>
+    {
+        return {};
+    }
+};
+
+struct ensure_started_t : __with_default_get_env<ensure_started_t>
+{
+    template <sender _Sender>
+        requires sender_in<_Sender, empty_env> &&
+                 __decay_copyable<env_of_t<_Sender>>
+    auto operator()(_Sender&& __sndr) const
+    {
+        if constexpr (sender_expr_for<_Sender, __ensure_started_t>)
+        {
+            return (_Sender&&)__sndr;
+        }
+        else
+        {
+            auto __domain = __get_early_domain(__sndr);
+            return stdexec::transform_sender(
+                __domain,
+                __make_sexpr<ensure_started_t>(__(), (_Sender&&)__sndr));
+        }
+        STDEXEC_UNREACHABLE();
+    }
+
+    template <sender _Sender, class _Env>
+        requires sender_in<_Sender, _Env> && __decay_copyable<env_of_t<_Sender>>
+    auto operator()(_Sender&& __sndr, _Env&& __env) const
+    {
+        if constexpr (sender_expr_for<_Sender, __ensure_started_t>)
+        {
+            return (_Sender&&)__sndr;
+        }
+        else
+        {
+            auto __domain = __get_late_domain(__sndr, __env);
+            return stdexec::transform_sender(
+                __domain,
+                __make_sexpr<ensure_started_t>(__(), (_Sender&&)__sndr),
+                (_Env&&)__env);
+        }
+        STDEXEC_UNREACHABLE();
+    }
+
+    STDEXEC_ATTRIBUTE((always_inline)) //
     __binder_back<ensure_started_t> operator()() const
     {
         return {{}, {}, {}};
     }
+
+    using _Sender = __1;
+    using __legacy_customizations_t = //
+        __types<tag_invoke_t(ensure_started_t,
+                             get_completion_scheduler_t<set_value_t>(
+                                 get_env_t(const _Sender&)),
+                             _Sender),
+                tag_invoke_t(ensure_started_t, _Sender)>;
+
+    template <class _CvrefSender, class... _Env>
+    using __receiver_t = stdexec::__t<
+        __meval<__receiver, __cvref_id<_CvrefSender>, __id<_Env>...>>;
+
+    template <class _Sender, class... _Env>
+        requires sender_to<__child_of<_Sender>,
+                           __receiver_t<__child_of<_Sender>, _Env...>>
+    static auto transform_sender(_Sender&& __sndr, _Env... __env)
+    {
+        return __sexpr_apply(
+            (_Sender&&)__sndr,
+            [&]<class _Child>(__ignore, __ignore, _Child&& __child) {
+            using __sh_state_t =
+                __t<__sh_state<__cvref_id<_Child>, __id<_Env>...>>;
+            auto __sh_state = __make_intrusive<__sh_state_t>(
+                (_Child&&)__child, std::move(__env)...);
+            return __make_sexpr<__ensure_started_t>(
+                __data{std::move(__sh_state)});
+        });
+    }
 };
 } // namespace __ensure_started
 
 using __ensure_started::ensure_started_t;
 inline constexpr ensure_started_t ensure_started{};
 
+STDEXEC_PRAGMA_PUSH()
+STDEXEC_PRAGMA_IGNORE_EDG(not_used_in_partial_spec_arg_list)
+
+/////////////////////////////////////////////////////////////////////////////
+// a receiver adaptor that augments its environment
+namespace __detail
+{
+template <auto _ReceiverPtr, auto... _EnvFns>
+struct __receiver_with;
+
+template <class _Operation, class _Receiver,
+          _Receiver _Operation::*_ReceiverPtr, auto... _EnvFns>
+struct __receiver_with<_ReceiverPtr, _EnvFns...>
+{
+    struct __t : receiver_adaptor<__t>
+    {
+        using __id = __receiver_with;
+        using __env_t =
+            __env::__env_join_t<__result_of<_EnvFns, _Operation*>...,
+                                env_of_t<_Receiver>>;
+
+        _Operation* __op_state_;
+
+        _Receiver&& base() && noexcept
+        {
+            return static_cast<_Receiver&&>(__op_state_->*_ReceiverPtr);
+        }
+
+        __env_t get_env() const noexcept
+        {
+            return __join_env(_EnvFns(__op_state_)...,
+                              stdexec::get_env(__op_state_->*_ReceiverPtr));
+        }
+    };
+};
+} // namespace __detail
+
+STDEXEC_PRAGMA_POP()
+
 //////////////////////////////////////////////////////////////////////////////
 // [execution.senders.adaptors.let_value]
 // [execution.senders.adaptors.let_error]
@@ -4755,65 +5465,121 @@
 template <class _Tp>
 using __decay_ref = __decay_t<_Tp>&;
 
+template <class _ReceiverId, class _SchedulerId>
+struct __operation_base_base_ : __immovable
+{
+    using _Receiver = stdexec::__t<_ReceiverId>;
+    using _Scheduler = stdexec::__t<_SchedulerId>;
+
+    _Receiver __rcvr_;   // the input (outer) receiver
+    STDEXEC_ATTRIBUTE((no_unique_address))
+    _Scheduler __sched_; // the input sender's completion scheduler
+};
+
+inline constexpr auto __get_scheduler_prop = [](auto* __op) noexcept {
+    return __mkprop(__op->__sched_, get_scheduler);
+};
+
+inline constexpr auto __get_domain_prop = [](auto*) noexcept {
+    return __mkprop(get_domain);
+};
+
+// A metafunction that computes the result sender type for a given set of
+// argument types
 template <class _Fun, class _Set>
-using __result_sender = //
+using __result_sender_t = //
     __transform<
         __q<__decay_ref>,
         __mbind_front<__mtry_catch_q<__call_result_t, __on_not_callable<_Set>>,
                       _Fun>>;
 
-template <class _Receiver, class _Fun, class _Set>
-using __op_state_for = __mcompose<__mbind_back_q<connect_result_t, _Receiver>,
-                                  __result_sender<_Fun, _Set>>;
+// FUTURE: when we have a scheduler query for "always completes inline",
+// then we can use that instead of hard-coding `__inln::__scheduler` here.
+template <class _Scheduler>
+concept __unknown_context =
+    __one_of<_Scheduler, __none_such, __inln::__scheduler>;
+
+// The receiver that gets connected to the result sender is the input receiver,
+// possibly augmented with the input sender's completion scheduler (which is
+// where the result sender will be started).
+template <class _Receiver, class _Scheduler>
+using __result_receiver_t = __if_c<
+    __unknown_context<_Scheduler>, _Receiver,
+    __t<__detail::__receiver_with<
+        &__operation_base_base_<__id<_Receiver>, __id<_Scheduler>>::__rcvr_,
+        __get_scheduler_prop, __get_domain_prop>>>;
+
+// If the input sender knows its completion scheduler, make it the current
+// scheduler in the environment seen by the result sender.
+template <class _Env, class _Scheduler>
+using __result_env_t =
+    __if_c<__unknown_context<_Scheduler>, _Env,
+           __env::__env_join_t<__env::__prop<_Scheduler(get_scheduler_t)>,
+                               __env::__prop<void(get_domain_t)>, _Env>>;
+
+// A metafunction that computes the type of the resulting operation state for a
+// given set of argument types.
+template <class _Receiver, class _Fun, class _Set, class _Sched>
+using __op_state_for = //
+    __mcompose<__mbind_back_q<connect_result_t,
+                              __result_receiver_t<_Receiver, _Sched>>,
+               __result_sender_t<_Fun, _Set>>;
 
 template <class _Set, class _Sig>
 struct __tfx_signal_
 {
-    template <class, class>
+    template <class, class, class>
     using __f = completion_signatures<_Sig>;
 };
 
 template <class _Set, class... _Args>
 struct __tfx_signal_<_Set, _Set(_Args...)>
 {
-    template <class _Env, class _Fun>
+    template <class _Env, class _Fun, class _Sched>
     using __f = //
         __try_make_completion_signatures<
-            __minvoke<__result_sender<_Fun, _Set>, _Args...>, _Env,
+            __minvoke<__result_sender_t<_Fun, _Set>, _Args...>,
+            __result_env_t<_Env, _Sched>,
             // because we don't know if connect-ing the result sender will
             // throw:
             completion_signatures<set_error_t(std::exception_ptr)>>;
 };
 
-template <class _Env, class _Fun, class _Set, class _Sig>
-using __tfx_signal_t = __minvoke<__tfx_signal_<_Set, _Sig>, _Env, _Fun>;
+// `_Sched` is the input sender's completion scheduler, or __none_such if it
+// doesn't have one.
+template <class _Env, class _Fun, class _Set, class _Sched, class _Sig>
+using __tfx_signal_t = __minvoke<__tfx_signal_<_Set, _Sig>, _Env, _Fun, _Sched>;
 
-template <class _ReceiverId, class _Fun, class _Set, class... _Tuples>
+template <class _ReceiverId, class _Fun, class _Set, class _SchedId,
+          class... _Tuples>
 struct __operation_base_
 {
     using _Receiver = stdexec::__t<_ReceiverId>;
+    using _Sched = stdexec::__t<_SchedId>;
 
-    struct __t : __immovable
+    struct __t : __operation_base_base_<_ReceiverId, _SchedId>
     {
         using __id = __operation_base_;
         using __results_variant_t = std::variant<std::monostate, _Tuples...>;
         using __op_state_variant_t = //
             __minvoke<
-                __transform<__uncurry<__op_state_for<_Receiver, _Fun, _Set>>,
-                            __nullable_variant_t>,
+                __transform<
+                    __uncurry<__op_state_for<_Receiver, _Fun, _Set, _Sched>>,
+                    __nullable_variant_t>,
                 _Tuples...>;
 
-        _Receiver __rcvr_;
         _Fun __fun_;
         __results_variant_t __args_;
         __op_state_variant_t __op_state3_;
     };
 };
 
-template <class _ReceiverId, class _Fun, class _Set, class... _Tuples>
+template <class _ReceiverId, class _Fun, class _Set, class _SchedId,
+          class... _Tuples>
 struct __receiver_
 {
     using _Receiver = stdexec::__t<_ReceiverId>;
+    using _Sched = stdexec::__t<_SchedId>;
     using _Env = env_of_t<_Receiver>;
 
     struct __t
@@ -4821,28 +5587,41 @@
         using is_receiver = void;
         using __id = __receiver_;
 
+        decltype(auto) __get_result_receiver() noexcept
+        {
+            if constexpr (same_as<__result_receiver_t<_Receiver, _Sched>,
+                                  _Receiver>)
+            {
+                return static_cast<_Receiver&&>(__op_state_->__rcvr_);
+            }
+            else
+            {
+                return __result_receiver_t<_Receiver, _Sched>{{}, __op_state_};
+            }
+        }
+
         template <__one_of<_Set> _Tag, class... _As>
             requires(1 == __v<__minvoke<__mcount<__decayed_tuple<_As...>>,
                                         _Tuples...>>) &&
-                    __minvocable<__result_sender<_Fun, _Set>, _As...> &&
-                    sender_to<__minvoke<__result_sender<_Fun, _Set>, _As...>,
-                              _Receiver>
+                    __minvocable<__result_sender_t<_Fun, _Set>, _As...> &&
+                    sender_to<__minvoke<__result_sender_t<_Fun, _Set>, _As...>,
+                              __result_receiver_t<_Receiver, _Sched>>
         friend void tag_invoke(_Tag, __t&& __self, _As&&... __as) noexcept
         {
             try
             {
                 using __tuple_t = __decayed_tuple<_As...>;
                 using __op_state_t =
-                    __minvoke<__op_state_for<_Receiver, _Fun, _Set>, _As...>;
+                    __minvoke<__op_state_for<_Receiver, _Fun, _Set, _Sched>,
+                              _As...>;
                 auto& __args =
                     __self.__op_state_->__args_.template emplace<__tuple_t>(
                         (_As&&)__as...);
                 auto& __op = __self.__op_state_->__op_state3_
                                  .template emplace<__op_state_t>(__conv{[&] {
                     return connect(
-                        std::apply(std::move(__self.__op_state_->__fun_),
-                                   __args),
-                        std::move(__self.__op_state_->__rcvr_));
+                        __apply(std::move(__self.__op_state_->__fun_), __args),
+                        __self.__get_result_receiver());
                 }});
                 start(__op);
             }
@@ -4868,17 +5647,23 @@
         }
 
         using __operation_base_t = stdexec::__t<
-            __operation_base_<_ReceiverId, _Fun, _Set, _Tuples...>>;
+            __operation_base_<_ReceiverId, _Fun, _Set, _SchedId, _Tuples...>>;
         __operation_base_t* __op_state_;
     };
 };
 
+template <class _Sender, class _Set>
+using __completion_sched = __query_result_or_t<get_completion_scheduler_t<_Set>,
+                                               env_of_t<_Sender>, __none_such>;
+
 template <class _CvrefSenderId, class _ReceiverId, class _Fun, class _Set>
 using __receiver = //
     stdexec::__t<__gather_completions_for<
         _Set, __cvref_t<_CvrefSenderId>, env_of_t<__t<_ReceiverId>>,
         __q<__decayed_tuple>,
-        __munique<__mbind_front_q<__receiver_, _ReceiverId, _Fun, _Set>>>>;
+        __munique<__mbind_front_q<
+            __receiver_, _ReceiverId, _Fun, _Set,
+            __id<__completion_sched<__cvref_t<_CvrefSenderId>, _Set>>>>>>;
 
 template <class _CvrefSenderId, class _ReceiverId, class _Fun, class _Set>
 using __operation_base = typename __receiver<_CvrefSenderId, _ReceiverId, _Fun,
@@ -4904,7 +5689,13 @@
 
         template <class _Receiver2>
         __t(_Sender&& __sndr, _Receiver2&& __rcvr, _Fun __fun) :
-            __op_base_t{{}, (_Receiver2&&)__rcvr, (_Fun&&)__fun},
+            __op_base_t{{{},
+                         (_Receiver2&&)__rcvr,
+                         query_or(get_completion_scheduler<_Set>,
+                                  get_env(__sndr), __none_such())},
+                        (_Fun&&)__fun,
+                        {},
+                        {}},
             __op_state2_(connect((_Sender&&)__sndr, __receiver_t{this}))
         {}
 
@@ -4912,109 +5703,167 @@
     };
 };
 
-template <class _SenderId, class _Fun, class _SetId>
+template <class _Sender, class _Fun, class _SetId>
+struct __sender_base
+{
+    using _Set = stdexec::__t<_SetId>;
+    using is_sender = void;
+
+    template <class _Self, class _Receiver>
+    using __operation_t = //
+        stdexec::__t<__operation<stdexec::__cvref_id<_Self, _Sender>,
+                                 stdexec::__id<_Receiver>, _Fun, _Set>>;
+    template <class _Self, class _Receiver>
+    using __receiver_t = __receiver<stdexec::__cvref_id<_Self, _Sender>,
+                                    stdexec::__id<_Receiver>, _Fun, _Set>;
+
+    template <class _CvrefSender>
+    using __completion_sched =
+        __query_result_or_t<get_completion_scheduler_t<_Set>,
+                            env_of_t<_CvrefSender>, __none_such>;
+
+    template <class _CvrefSender, class _Env>
+    using __completions = //
+        __mapply<__transform<__mbind_front_q<__tfx_signal_t, _Env, _Fun, _Set,
+                                             __completion_sched<_Sender>>,
+                             __q<__concat_completion_signatures_t>>,
+                 __completion_signatures_of_t<_Sender, _Env>>;
+
+    template <__decays_to_derived_from<__sender_base> _Self, receiver _Receiver>
+        requires sender_to<__copy_cvref_t<_Self, _Sender>,
+                           __receiver_t<_Self, _Receiver>>
+    friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr)
+        -> __operation_t<_Self, _Receiver>
+    {
+        return __operation_t<_Self, _Receiver>{((_Self&&)__self).__sndr_,
+                                               (_Receiver&&)__rcvr,
+                                               ((_Self&&)__self).__fun_};
+    }
+
+    template <__decays_to_derived_from<__sender_base> _Self, class _Env>
+    friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
+        -> __completions<__copy_cvref_t<_Self, _Sender>, _Env>
+    {
+        return {};
+    }
+
+    // BUGBUG better would be to port the `let_[value|error|stopped]` algorithms
+    // to __sexpr
+    template <class _Self, class _ApplyFun>
+    static auto apply(_Self&& __self, _ApplyFun __fun) -> __call_result_t<
+        _ApplyFun,
+        _SetId, // Actually one of let_value_t, let_error_t, let_stopped_t
+        __copy_cvref_t<_Self, _Fun>, __copy_cvref_t<_Self, _Sender>>
+    {
+        return ((_ApplyFun&&)__fun)(_SetId(), ((_Self&&)__self).__fun_,
+                                    ((_Self&&)__self).__sndr_);
+    }
+
+    _Sender __sndr_;
+    _Fun __fun_;
+};
+
+template <class _SenderId, class _Fun, class _SetId,
+          class _Domain = dependent_domain>
 struct __sender
 {
-    using _Sender = stdexec::__t<_SenderId>;
-    using _Set = stdexec::__t<_SetId>;
-
-    struct __t
+    struct __t : __sender_base<stdexec::__t<_SenderId>, _Fun, _SetId>
     {
         using __id = __sender;
-        using is_sender = void;
-
-        template <class _Self, class _Receiver>
-        using __operation_t = //
-            stdexec::__t<__operation<stdexec::__cvref_id<_Self, _Sender>,
-                                     stdexec::__id<_Receiver>, _Fun, _Set>>;
-        template <class _Self, class _Receiver>
-        using __receiver_t = __receiver<stdexec::__cvref_id<_Self, _Sender>,
-                                        stdexec::__id<_Receiver>, _Fun, _Set>;
-
-        template <class _Sender, class _Env>
-        using __completions = //
-            __mapply<
-                __transform<__mbind_front_q<__tfx_signal_t, _Env, _Fun, _Set>,
-                            __q<__concat_completion_signatures_t>>,
-                __completion_signatures_of_t<_Sender, _Env>>;
-
-        template <__decays_to<__t> _Self, receiver _Receiver>
-            requires sender_to<__copy_cvref_t<_Self, _Sender>,
-                               __receiver_t<_Self, _Receiver>>
-        friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr)
-            -> __operation_t<_Self, _Receiver>
-        {
-            return __operation_t<_Self, _Receiver>{((_Self&&)__self).__sndr_,
-                                                   (_Receiver&&)__rcvr,
-                                                   ((_Self&&)__self).__fun_};
-        }
 
         friend auto tag_invoke(get_env_t, const __t& __self) noexcept
-            -> env_of_t<const _Sender&>
-        {
-            return get_env(__self.__sndr_);
+        /*-> env_of_t<const _Sender&>*/ {
+            return __join_env(__mkprop(_Domain(), get_domain),
+                              get_env(__self.__sndr_));
         }
-
-        template <__decays_to<__t> _Self, class _Env>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
-            -> dependent_completion_signatures<_Env>;
-
-        template <__decays_to<__t> _Self, class _Env>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
-            -> __completions<__copy_cvref_t<_Self, _Sender>, _Env>
-            requires true;
-
-        _Sender __sndr_;
-        _Fun __fun_;
     };
 };
 
 template <class _LetTag, class _SetTag>
-struct __let_xxx_t
+struct __let_xxx_t : __with_default_get_env<_LetTag>
 {
+    using _Sender = __1;
+    using _Function = __0;
+    using __legacy_customizations_t =
+        __types<tag_invoke_t(_LetTag,
+                             get_completion_scheduler_t<set_value_t>(
+                                 get_env_t(const _Sender&)),
+                             _Sender, _Function),
+                tag_invoke_t(_LetTag, _Sender, _Function)>;
+
     using __t = _SetTag;
-    template <class _Sender, class _Fun>
-    using __sender = stdexec::__t<
-        __let::__sender<stdexec::__id<__decay_t<_Sender>>, _Fun, _LetTag>>;
+    template <class _Sender, class _Fun, class _Domain = dependent_domain>
+    using __sender =
+        stdexec::__t<__let::__sender<stdexec::__id<__decay_t<_Sender>>, _Fun,
+                                     _LetTag, _Domain>>;
 
     template <sender _Sender, __movable_value _Fun>
-        requires __tag_invocable_with_completion_scheduler<_LetTag, set_value_t,
-                                                           _Sender, _Fun>
-    sender auto operator()(_Sender&& __sndr, _Fun __fun) const
-        noexcept(nothrow_tag_invocable<
-                 _LetTag, __completion_scheduler_for<_Sender, set_value_t>,
-                 _Sender, _Fun>)
+    auto operator()(_Sender&& __sndr, _Fun __fun) const
     {
-        auto __sched = get_completion_scheduler<set_value_t>(get_env(__sndr));
-        return tag_invoke(_LetTag{}, std::move(__sched), (_Sender&&)__sndr,
-                          (_Fun&&)__fun);
-    }
-
-    template <sender _Sender, __movable_value _Fun>
-        requires(!__tag_invocable_with_completion_scheduler<
-                    _LetTag, set_value_t, _Sender, _Fun>) &&
-                tag_invocable<_LetTag, _Sender, _Fun>
-    sender auto operator()(_Sender&& __sndr, _Fun __fun) const
-        noexcept(nothrow_tag_invocable<_LetTag, _Sender, _Fun>)
-    {
-        return tag_invoke(_LetTag{}, (_Sender&&)__sndr, (_Fun&&)__fun);
-    }
-
-    template <sender _Sender, __movable_value _Fun>
-        requires(!__tag_invocable_with_completion_scheduler<
-                    _LetTag, set_value_t, _Sender, _Fun>) &&
-                (!tag_invocable<_LetTag, _Sender, _Fun>) &&
-                sender<__sender<_Sender, _Fun>>
-    __sender<_Sender, _Fun> operator()(_Sender&& __sndr, _Fun __fun) const
-    {
-        return __sender<_Sender, _Fun>{(_Sender&&)__sndr, (_Fun&&)__fun};
+        auto __domain = __get_early_domain(__sndr);
+        return stdexec::transform_sender(
+            __domain,
+            __sender<_Sender, _Fun>{{(_Sender&&)__sndr, (_Fun&&)__fun}});
     }
 
     template <class _Fun>
+    STDEXEC_ATTRIBUTE((always_inline)) //
     __binder_back<_LetTag, _Fun> operator()(_Fun __fun) const
     {
         return {{}, {}, {(_Fun&&)__fun}};
     }
+
+    // Compute all the domains of all the result senders and make sure they're
+    // all the same
+    template <class _Child, class _Fun, class _Env>
+    using __result_domain_t = __gather_completions_for<
+        _SetTag, _Child, _Env,
+        __mtry_catch<__mbind_front_q<__call_result_t, _Fun>,
+                     __on_not_callable<_SetTag>>,
+        __q<__domain::__common_domain_t>>;
+
+    static auto get_env(__ignore) noexcept
+    {
+        return __mkprop(dependent_domain(), get_domain);
+    }
+
+    template <sender_expr_for<_LetTag> _Sender, class _Env>
+    static decltype(auto) transform_env(_Sender&& __sndr, const _Env& __env)
+    {
+        return __sexpr_apply(
+            (_Sender&&)__sndr,
+            [&]<class _Fun, sender_in<_Env> _Child>(
+                __ignore, _Fun&&, _Child&& __child) -> decltype(auto) {
+            using _Scheduler = __completion_sched<_Child, _SetTag>;
+            if constexpr (__unknown_context<_Scheduler>)
+            {
+                return (__env);
+            }
+            else
+            {
+                return __join_env(__mkprop(get_completion_scheduler<_SetTag>(
+                                               stdexec::get_env(__child)),
+                                           get_scheduler),
+                                  __mkprop(get_domain), __env);
+            }
+            STDEXEC_UNREACHABLE();
+        });
+    }
+
+    template <sender_expr_for<_LetTag> _Sender, class _Env>
+        requires same_as<__early_domain_of_t<_Sender>, dependent_domain>
+    static decltype(auto) transform_sender(_Sender&& __sndr, const _Env& __env)
+    {
+        return __sexpr_apply((_Sender&&)__sndr,
+                             [&]<class _Fun, sender_in<_Env> _Child>(
+                                 __ignore, _Fun&& __fun, _Child&& __child) {
+            // TODO: propagate errors here
+            using _Domain = __result_domain_t<_Child, _Fun, _Env>;
+            static_assert(__none_of<_Domain, __none_such, dependent_domain>);
+            return __sender<_Child, _Fun, _Domain>{
+                {(_Child&&)__child, (_Fun&&)__fun}};
+        });
+    }
 };
 
 struct let_value_t : __let::__let_xxx_t<let_value_t, set_value_t>
@@ -5034,6 +5883,14 @@
 using __let::let_stopped_t;
 inline constexpr let_stopped_t let_stopped{};
 
+// BUGBUG this will also be unnecessary when `on` returns a __sexpr
+namespace __detail
+{
+template <class _SenderId, class _Fun, class _SetId>
+extern __mconst<__let::__sender<__name_of<__t<_SenderId>>, _Fun, _SetId>>
+    __name_of_v<__let::__sender<_SenderId, _Fun, _SetId>>;
+}
+
 /////////////////////////////////////////////////////////////////////////////
 // [execution.senders.adaptors.stopped_as_optional]
 // [execution.senders.adaptors.stopped_as_error]
@@ -5048,46 +5905,51 @@
     using _Sender = stdexec::__t<_CvrefSenderId>;
     using _Receiver = stdexec::__t<_ReceiverId>;
 
-    struct __t : receiver_adaptor<__t>
+    struct __t
     {
+        using is_receiver = void;
         using __id = __receiver;
 
-        _Receiver&& base() && noexcept
-        {
-            return (_Receiver&&)__op_->__rcvr_;
-        }
-
-        const _Receiver& base() const& noexcept
-        {
-            return __op_->__rcvr_;
-        }
-
-        template <class _Ty>
-        void set_value(_Ty&& __a) && noexcept
+        template <same_as<set_value_t> _Tag, class _Ty>
+        friend void tag_invoke(_Tag, __t&& __self, _Ty&& __a) noexcept
         {
             try
             {
                 using _Value = __decay_t<
                     __single_sender_value_t<_Sender, env_of_t<_Receiver>>>;
                 static_assert(constructible_from<_Value, _Ty>);
-                stdexec::set_value(((__t&&)*this).base(),
+                stdexec::set_value((_Receiver&&)__self.__op_->__rcvr_,
                                    std::optional<_Value>{(_Ty&&)__a});
             }
             catch (...)
             {
-                stdexec::set_error(((__t&&)*this).base(),
+                stdexec::set_error((_Receiver&&)__self.__op_->__rcvr_,
                                    std::current_exception());
             }
         }
 
-        void set_stopped() && noexcept
+        template <same_as<set_error_t> _Tag, class _Error>
+        friend void tag_invoke(_Tag, __t&& __self, _Error&& __error) noexcept
+        {
+            stdexec::set_error((_Receiver&&)__self.__op_->__rcvr_,
+                               (_Error&&)__error);
+        }
+
+        template <same_as<set_stopped_t> _Tag>
+        friend void tag_invoke(_Tag, __t&& __self) noexcept
         {
             using _Value = __decay_t<
                 __single_sender_value_t<_Sender, env_of_t<_Receiver>>>;
-            stdexec::set_value(((__t&&)*this).base(),
+            stdexec::set_value((_Receiver&&)__self.__op_->__rcvr_,
                                std::optional<_Value>{std::nullopt});
         }
 
+        template <same_as<get_env_t> _Tag>
+        friend env_of_t<_Receiver> tag_invoke(_Tag, const __t& __self) noexcept
+        {
+            return stdexec::get_env(__self.__op_->__rcvr_);
+        }
+
         stdexec::__t<__operation<_CvrefSenderId, _ReceiverId>>* __op_;
     };
 };
@@ -5105,7 +5967,7 @@
 
         __t(_Sender&& __sndr, _Receiver&& __rcvr) :
             __rcvr_((_Receiver&&)__rcvr),
-            __op_state_(connect((_Sender&&)__sndr, __receiver_t{{}, this}))
+            __op_state_(connect((_Sender&&)__sndr, __receiver_t{this}))
         {}
 
         STDEXEC_IMMOVABLE(__t);
@@ -5120,74 +5982,77 @@
     };
 };
 
-template <class _SenderId>
-struct __sender
-{
-    using _Sender = stdexec::__t<_SenderId>;
-
-    struct __t
-    {
-        using __id = __sender;
-        using is_sender = void;
-
-        template <class _Self, class _Receiver>
-        using __operation_t =
-            stdexec::__t<__operation<stdexec::__cvref_id<_Self, _Sender>,
-                                     stdexec::__id<_Receiver>>>;
-        template <class _Self, class _Receiver>
-        using __receiver_t =
-            stdexec::__t<__receiver<stdexec::__cvref_id<_Self, _Sender>,
-                                    stdexec::__id<_Receiver>>>;
-
-        template <__decays_to<__t> _Self, receiver _Receiver>
-            requires __single_typed_sender<__copy_cvref_t<_Self, _Sender>,
-                                           env_of_t<_Receiver>> &&
-                     sender_to<__copy_cvref_t<_Self, _Sender>,
-                               __receiver_t<_Self, _Receiver>>
-        friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr)
-            -> __operation_t<_Self, _Receiver>
-        {
-            return {((_Self&&)__self).__sndr_, (_Receiver&&)__rcvr};
-        }
-
-        friend auto tag_invoke(get_env_t, const __t& __self) noexcept
-            -> env_of_t<const _Sender&>
-        {
-            return get_env(__self.__sndr_);
-        }
-
-        template <class... _Tys>
-            requires(sizeof...(_Tys) == 1)
-        using __set_value_t = completion_signatures<set_value_t(
-            std::optional<__decay_t<_Tys>>...)>;
-
-        template <class _Ty>
-        using __set_error_t = completion_signatures<set_error_t(_Ty)>;
-
-        template <__decays_to<__t> _Self, class _Env>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
-            -> make_completion_signatures<
-                __copy_cvref_t<_Self, _Sender>, _Env,
-                completion_signatures<set_error_t(std::exception_ptr)>,
-                __set_value_t, __set_error_t, completion_signatures<>>;
-
-        _Sender __sndr_;
-    };
-};
-
-struct stopped_as_optional_t
+struct stopped_as_optional_t : __with_default_get_env<stopped_as_optional_t>
 {
     template <sender _Sender>
     auto operator()(_Sender&& __sndr) const
-        -> __t<__sender<stdexec::__id<__decay_t<_Sender>>>>
     {
-        return {(_Sender&&)__sndr};
+        return __make_sexpr<stopped_as_optional_t>(__(), (_Sender&&)__sndr);
     }
 
+    STDEXEC_ATTRIBUTE((always_inline)) //
     __binder_back<stopped_as_optional_t> operator()() const noexcept
     {
         return {};
     }
+
+#if STDEXEC_FRIENDSHIP_IS_LEXICAL()
+  private:
+    template <class...>
+    friend struct stdexec::__sexpr;
+#endif
+
+    template <class _CvrefSender, class _Receiver>
+    using __operation_t =
+        stdexec::__t<__operation<stdexec::__cvref_id<_CvrefSender>,
+                                 stdexec::__id<_Receiver>>>;
+    template <class _CvrefSender, class _Receiver>
+    using __receiver_t =
+        stdexec::__t<__receiver<stdexec::__cvref_id<_CvrefSender>,
+                                stdexec::__id<_Receiver>>>;
+
+    template <class _Receiver>
+    struct __connect_fn
+    {
+        _Receiver __rcvr_;
+
+        template <class _Child>
+        __operation_t<_Child, _Receiver> operator()(stopped_as_optional_t, __,
+                                                    _Child&& __child)
+        {
+            return {(_Child&&)__child, std::move(__rcvr_)};
+        }
+    };
+
+    template <sender_expr_for<stopped_as_optional_t> _Self, receiver _Receiver>
+        requires __single_typed_sender<__child_of<_Self>,
+                                       env_of_t<_Receiver>> &&
+                 sender_to<__child_of<_Self>,
+                           __receiver_t<__child_of<_Self>, _Receiver>>
+    static __operation_t<__child_of<_Self>, _Receiver> connect(_Self&& __self,
+                                                               _Receiver __rcvr)
+    {
+        return __sexpr_apply((_Self&&)__self,
+                             __connect_fn<_Receiver>{(_Receiver&&)__rcvr});
+    }
+
+    template <class... _Tys>
+        requires(sizeof...(_Tys) == 1)
+    using __set_value_t =
+        completion_signatures<set_value_t(std::optional<__decay_t<_Tys>>...)>;
+
+    template <class _Ty>
+    using __set_error_t = completion_signatures<set_error_t(_Ty)>;
+
+    template <sender_expr_for<stopped_as_optional_t> _Self, class _Env>
+    static auto get_completion_signatures(_Self&&, _Env&&)
+        -> make_completion_signatures<
+            __child_of<_Self>, _Env,
+            completion_signatures<set_error_t(std::exception_ptr)>,
+            __set_value_t, __set_error_t, completion_signatures<>>
+    {
+        return {};
+    }
 };
 
 struct stopped_as_error_t
@@ -5204,6 +6069,7 @@
     }
 
     template <__movable_value _Error>
+    STDEXEC_ATTRIBUTE((always_inline)) //
     auto operator()(_Error __err) const
         -> __binder_back<stopped_as_error_t, _Error>
     {
@@ -5249,7 +6115,7 @@
         using __id = __operation;
 
         run_loop* __loop_;
-        STDEXEC_NO_UNIQUE_ADDRESS _Receiver __rcvr_;
+        STDEXEC_ATTRIBUTE((no_unique_address)) _Receiver __rcvr_;
 
         static void __execute_impl(__task* __p) noexcept
         {
@@ -5497,8 +6363,8 @@
                       __mbind_front_q<__bind_completions_t, _Sender, _Env>>,
         set_value_t, set_error_t, set_stopped_t>>;
 
-template <class _SchedulerId, class _CvrefSenderId, class _ReceiverId>
-struct __operation1;
+template <class _SchedulerId, class _VariantId, class _ReceiverId>
+struct __operation1_base;
 
 // This receiver is to be completed on the execution context
 // associated with the scheduler. When the source sender
@@ -5507,7 +6373,7 @@
 // read the completion out of the operation state and forward it
 // to the output receiver after transitioning to the scheduler's
 // context.
-template <class _SchedulerId, class _CvrefSenderId, class _ReceiverId>
+template <class _SchedulerId, class _VariantId, class _ReceiverId>
 struct __receiver2
 {
     using _Receiver = stdexec::__t<_ReceiverId>;
@@ -5516,8 +6382,7 @@
     {
         using is_receiver = void;
         using __id = __receiver2;
-        stdexec::__t<__operation1<_SchedulerId, _CvrefSenderId, _ReceiverId>>*
-            __op_state_;
+        __operation1_base<_SchedulerId, _VariantId, _ReceiverId>* __op_state_;
 
         // If the work is successfully scheduled on the new execution
         // context and is ready to run, forward the completion signal in
@@ -5550,19 +6415,19 @@
 // context of the scheduler. That second receiver will read the
 // completion information out of the operation state and propagate
 // it to the output receiver from within the desired context.
-template <class _SchedulerId, class _CvrefSenderId, class _ReceiverId>
+template <class _SchedulerId, class _VariantId, class _ReceiverId>
 struct __receiver1
 {
     using _Scheduler = stdexec::__t<_SchedulerId>;
     using _Receiver = stdexec::__t<_ReceiverId>;
     using __receiver2_t =
-        stdexec::__t<__receiver2<_SchedulerId, _CvrefSenderId, _ReceiverId>>;
+        stdexec::__t<__receiver2<_SchedulerId, _VariantId, _ReceiverId>>;
 
     struct __t
     {
+        using __id = __receiver1;
         using is_receiver = void;
-        stdexec::__t<__operation1<_SchedulerId, _CvrefSenderId, _ReceiverId>>*
-            __op_state_;
+        __operation1_base<_SchedulerId, _VariantId, _ReceiverId>* __op_state_;
 
         template <class... _Args>
         static constexpr bool __nothrow_complete_ =
@@ -5589,8 +6454,8 @@
                                _Args&&... __args) noexcept
         {
             __try_call((_Receiver&&)__self.__op_state_->__rcvr_,
-                       __fun_c<__complete_<_Tag, _Args...>>, (_Tag&&)__tag,
-                       (__t&&)__self, (_Args&&)__args...);
+                       __function_constant_v<__complete_<_Tag, _Args...>>,
+                       (_Tag&&)__tag, (__t&&)__self, (_Args&&)__args...);
         }
 
         friend auto tag_invoke(get_env_t, const __t& __self) noexcept
@@ -5601,63 +6466,74 @@
     };
 };
 
+template <class _SchedulerId, class _VariantId, class _ReceiverId>
+struct __operation1_base : __immovable
+{
+    using _Scheduler = stdexec::__t<_SchedulerId>;
+    using _Receiver = stdexec::__t<_ReceiverId>;
+    using _Variant = stdexec::__t<_VariantId>;
+    using __receiver2_t =
+        stdexec::__t<__receiver2<_SchedulerId, _VariantId, _ReceiverId>>;
+
+    _Scheduler __sched_;
+    _Receiver __rcvr_;
+    _Variant __data_;
+    connect_result_t<schedule_result_t<_Scheduler>, __receiver2_t> __state2_;
+
+    __operation1_base(_Scheduler __sched, _Receiver&& __rcvr) :
+        __sched_((_Scheduler&&)__sched), __rcvr_((_Receiver&&)__rcvr),
+        __state2_(connect(schedule(__sched_), __receiver2_t{this}))
+    {}
+
+    void __complete() noexcept
+    {
+        STDEXEC_ASSERT(!__data_.valueless_by_exception());
+        std::visit(
+            [this]<class _Tup>(_Tup& __tupl) -> void {
+            if constexpr (same_as<_Tup, std::monostate>)
+            {
+                std::terminate(); // reaching this indicates a bug in
+                                  // schedule_from
+            }
+            else
+            {
+                __apply(
+                    [&]<class... _Args>(auto __tag, _Args&... __args) -> void {
+                    __tag((_Receiver&&)__rcvr_, (_Args&&)__args...);
+                },
+                    __tupl);
+            }
+        },
+            __data_);
+    }
+};
+
 template <class _SchedulerId, class _CvrefSenderId, class _ReceiverId>
 struct __operation1
 {
     using _Scheduler = stdexec::__t<_SchedulerId>;
     using _CvrefSender = stdexec::__cvref_t<_CvrefSenderId>;
     using _Receiver = stdexec::__t<_ReceiverId>;
-    using __receiver1_t =
-        stdexec::__t<__receiver1<_SchedulerId, _CvrefSenderId, _ReceiverId>>;
-    using __receiver2_t =
-        stdexec::__t<__receiver2<_SchedulerId, _CvrefSenderId, _ReceiverId>>;
     using __variant_t = __variant_for_t<_CvrefSender, env_of_t<_Receiver>>;
+    using __receiver1_t = stdexec::__t<
+        __receiver1<_SchedulerId, stdexec::__id<__variant_t>, _ReceiverId>>;
+    using __base_t = __operation1_base<_SchedulerId, stdexec::__id<__variant_t>,
+                                       _ReceiverId>;
 
-    struct __t
+    struct __t : __base_t
     {
         using __id = __operation1;
-        _Scheduler __sched_;
-        _Receiver __rcvr_;
-        __variant_t __data_;
         connect_result_t<_CvrefSender, __receiver1_t> __state1_;
-        connect_result_t<schedule_result_t<_Scheduler>, __receiver2_t>
-            __state2_;
 
         __t(_Scheduler __sched, _CvrefSender&& __sndr, _Receiver&& __rcvr) :
-            __sched_((_Scheduler&&)__sched), __rcvr_((_Receiver&&)__rcvr),
-            __state1_(connect((_CvrefSender&&)__sndr, __receiver1_t{this})),
-            __state2_(connect(schedule(__sched_), __receiver2_t{this}))
+            __base_t{(_Scheduler&&)__sched, (_Receiver&&)__rcvr},
+            __state1_(connect((_CvrefSender&&)__sndr, __receiver1_t{this}))
         {}
 
-        STDEXEC_IMMOVABLE(__t);
-
         friend void tag_invoke(start_t, __t& __op_state) noexcept
         {
             start(__op_state.__state1_);
         }
-
-        void __complete() noexcept
-        {
-            STDEXEC_ASSERT(!__data_.valueless_by_exception());
-            std::visit(
-                [&]<class _Tup>(_Tup& __tupl) -> void {
-                if constexpr (same_as<_Tup, std::monostate>)
-                {
-                    std::terminate(); // reaching this indicates a bug in
-                                      // schedule_from
-                }
-                else
-                {
-                    std::apply(
-                        [&]<class... _Args>(auto __tag,
-                                            _Args&... __args) -> void {
-                        __tag((_Receiver&&)__rcvr_, (_Args&&)__args...);
-                    },
-                        __tupl);
-                }
-            },
-                __data_);
-        }
     };
 };
 
@@ -5670,116 +6546,131 @@
                 __mcompose<__q<completion_signatures>, __qf<_Tag>>>;
 
 template <class _SchedulerId>
-struct __env
+struct __environ
 {
-    using _Scheduler = stdexec::__t<_SchedulerId>;
-
-    struct __t
+    struct __t :
+        __env::__prop<stdexec::__t<_SchedulerId>(
+            get_completion_scheduler_t<set_value_t>,
+            get_completion_scheduler_t<set_stopped_t>)>
     {
-        using __id = __env;
+        using __id = __environ;
 
-        _Scheduler __sched_;
-
-        template <__one_of<set_value_t, set_stopped_t> _Tag>
-        friend _Scheduler tag_invoke(get_completion_scheduler_t<_Tag>,
-                                     const __t& __self) noexcept
+        template <same_as<get_domain_t> _Key>
+        friend auto tag_invoke(_Key, const __t& __self) noexcept
         {
-            return __self.__sched_;
+            return query_or(get_domain, __self.__value_, default_domain());
         }
     };
 };
 
-template <class _SchedulerId, class _SenderId>
-struct __sender
+template <class... _Ts>
+using __all_nothrow_decay_copyable =
+    __mbool<(__nothrow_decay_copyable<_Ts> && ...)>;
+
+template <class _CvrefSender, class _Env>
+using __all_values_and_errors_nothrow_decay_copyable = //
+    __mand<
+        __try_error_types_of_t<_CvrefSender, _Env,
+                               __q<__all_nothrow_decay_copyable>>,
+        __try_value_types_of_t<_CvrefSender, _Env,
+                               __q<__all_nothrow_decay_copyable>, __q<__mand>>>;
+
+template <class _CvrefSender, class _Env>
+using __with_error_t = //
+    __if<__all_values_and_errors_nothrow_decay_copyable<_CvrefSender, _Env>,
+         completion_signatures<>, __with_exception_ptr>;
+
+template <class _Scheduler, class _CvrefSender, class _Env>
+using __completions_t = //
+    __try_make_completion_signatures<
+        _CvrefSender, _Env,
+        __try_make_completion_signatures<schedule_result_t<_Scheduler>, _Env,
+                                         __with_error_t<_CvrefSender, _Env>,
+                                         __mconst<completion_signatures<>>>,
+        __decay_signature<set_value_t>, __decay_signature<set_error_t>>;
+
+inline auto __get_env_fn() noexcept
 {
-    using _Scheduler = stdexec::__t<_SchedulerId>;
-    using _Sender = stdexec::__t<_SenderId>;
-    using _Env = stdexec::__t<__env<_SchedulerId>>;
-
-    struct __t
-    {
-        using __id = __sender;
-        using is_sender = void;
-        _Env __env_;
-        _Sender __sndr_;
-
-        template <class _Self, class _Receiver>
-        using __receiver_t = //
-            stdexec::__t<
-                __receiver1<_SchedulerId, stdexec::__cvref_id<_Self, _Sender>,
-                            stdexec::__id<_Receiver>>>;
-
-        template <__decays_to<__t> _Self, receiver _Receiver>
-            requires sender_to<__copy_cvref_t<_Self, _Sender>,
-                               __receiver_t<_Self, _Receiver>>
-        friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr) //
-            -> stdexec::__t<
-                __operation1<_SchedulerId, stdexec::__cvref_id<_Self, _Sender>,
-                             stdexec::__id<_Receiver>>>
-        {
-            return {__self.__env_.__sched_, ((_Self&&)__self).__sndr_,
-                    (_Receiver&&)__rcvr};
-        }
-
-        template <class... _Ts>
-        using __all_nothrow_decay_copyable =
-            __mbool<(__nothrow_decay_copyable<_Ts> && ...)>;
-
-        template <class _Self, class _Env>
-        using __all_values_and_errors_nothrow_decay_copyable =
-            __mand<error_types_of_t<__copy_cvref_t<_Self, _Sender>, _Env,
-                                    __all_nothrow_decay_copyable>,
-                   value_types_of_t<__copy_cvref_t<_Self, _Sender>, _Env,
-                                    __all_nothrow_decay_copyable, __mand>>;
-
-        template <class _Self, class _Env>
-        using __with_error_t =
-            __if<__all_values_and_errors_nothrow_decay_copyable<_Self, _Env>,
-                 completion_signatures<>, __with_exception_ptr>;
-
-        template <class _Self, class _Env>
-        using __completions_t = //
-            __try_make_completion_signatures<
-                __copy_cvref_t<_Self, _Sender>, _Env,
-                __try_make_completion_signatures<
-                    schedule_result_t<_Scheduler>, _Env,
-                    __with_error_t<_Self, _Env>,
-                    __mconst<completion_signatures<>>>,
-                __decay_signature<set_value_t>, __decay_signature<set_error_t>>;
-
-        template <__decays_to<__t> _Self, class _Env>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
-            -> dependent_completion_signatures<_Env>;
-
-        template <__decays_to<__t> _Self, class _Env>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
-            -> __completions_t<_Self, _Env>
-            requires true;
-
-        friend const _Env& tag_invoke(get_env_t, const __t& __self) noexcept
-        {
-            return __self.__env_;
-        }
+    return [](__ignore, const auto& __data,
+              const auto& __child) noexcept -> decltype(auto) {
+        return __join_env(__data, stdexec::get_env(__child));
     };
-};
+}
 
 struct schedule_from_t
 {
     template <scheduler _Scheduler, sender _Sender>
-        requires tag_invocable<schedule_from_t, _Scheduler, _Sender>
     auto operator()(_Scheduler&& __sched, _Sender&& __sndr) const
-        noexcept(nothrow_tag_invocable<schedule_from_t, _Scheduler, _Sender>)
-            -> tag_invoke_result_t<schedule_from_t, _Scheduler, _Sender>
     {
-        return tag_invoke(*this, (_Scheduler&&)__sched, (_Sender&&)__sndr);
+        using _Env = __t<__environ<__id<__decay_t<_Scheduler>>>>;
+        auto __env = _Env{{(_Scheduler&&)__sched}};
+        auto __domain = query_or(get_domain, __sched, default_domain());
+        return stdexec::transform_sender(
+            __domain,
+            __make_sexpr<schedule_from_t>(std::move(__env), (_Sender&&)__sndr));
     }
 
-    template <scheduler _Scheduler, sender _Sender>
-    auto operator()(_Scheduler&& __sched, _Sender&& __sndr) const
-        -> stdexec::__t<__sender<stdexec::__id<__decay_t<_Scheduler>>,
-                                 stdexec::__id<__decay_t<_Sender>>>>
+    using _Sender = __1;
+    using _Env = __0;
+    using __legacy_customizations_t = __types<tag_invoke_t(
+        schedule_from_t, get_completion_scheduler_t<set_value_t>(_Env&),
+        _Sender)>;
+
+#if STDEXEC_FRIENDSHIP_IS_LEXICAL()
+  private:
+    template <class...>
+    friend struct stdexec::__sexpr;
+#endif
+
+    template <class _Sender>
+    using __env_t =
+        __sexpr_apply_result_t<const _Sender&, __result_of<__get_env_fn>>;
+
+    template <class _Sender>
+    using __scheduler_t =
+        __decay_t<__call_result_t<get_completion_scheduler_t<set_value_t>,
+                                  __env_t<_Sender>>>;
+
+    template <class _Sender, class _Receiver>
+    using __receiver_t = //
+        stdexec::__t<__receiver1<stdexec::__id<__scheduler_t<_Sender>>,
+                                 stdexec::__id<__variant_for_t<
+                                     __child_of<_Sender>, env_of_t<_Receiver>>>,
+                                 stdexec::__id<_Receiver>>>;
+
+    template <class _Sender, class _Receiver>
+    using __operation_t =          //
+        stdexec::__t<__operation1< //
+            stdexec::__id<__scheduler_t<_Sender>>,
+            stdexec::__cvref_id<__child_of<_Sender>>,
+            stdexec::__id<_Receiver>>>;
+
+    template <sender_expr_for<schedule_from_t> _Sender>
+    static __env_t<_Sender> get_env(const _Sender& __sndr) noexcept
     {
-        return {{(_Scheduler&&)__sched}, (_Sender&&)__sndr};
+        return __sexpr_apply(__sndr, __get_env_fn());
+    }
+
+    template <sender_expr_for<schedule_from_t> _Sender, class _Env>
+    static auto get_completion_signatures(_Sender&&, const _Env&) noexcept
+        -> __completions_t<__scheduler_t<_Sender>, __child_of<_Sender>, _Env>
+    {
+        return {};
+    }
+
+    template <sender_expr_for<schedule_from_t> _Sender, receiver _Receiver>
+        requires sender_to<__child_of<_Sender>,
+                           __receiver_t<_Sender, _Receiver>>
+    static auto connect(_Sender&& __sndr, _Receiver __rcvr) //
+        -> __operation_t<_Sender, _Receiver>
+    {
+        return __sexpr_apply((_Sender&&)__sndr,
+                             [&]<class _Data, class _Child>(
+                                 __ignore, _Data&& __data, _Child&& __child)
+                                 -> __operation_t<_Sender, _Receiver> {
+            auto __sched = get_completion_scheduler<set_value_t>(__data);
+            return {__sched, (_Child&&)__child, (_Receiver&&)__rcvr};
+        });
     }
 };
 } // namespace __schedule_from
@@ -5791,52 +6682,76 @@
 // [execution.senders.adaptors.transfer]
 namespace __transfer
 {
+using __schedule_from::__environ;
+
+template <class _Env>
+using __scheduler_t = __result_of<get_completion_scheduler<set_value_t>, _Env>;
+
+template <class _Sender>
+using __lowered_t = //
+    __result_of<schedule_from, __scheduler_t<__data_of<_Sender>>,
+                __child_of<_Sender>>;
+
+inline auto __get_env_fn() noexcept
+{
+    return [](__ignore, const auto& __data, const auto& __child) noexcept {
+        return __join_env(__data, stdexec::get_env(__child));
+    };
+}
+
 struct transfer_t
 {
     template <sender _Sender, scheduler _Scheduler>
-        requires __tag_invocable_with_completion_scheduler<
-            transfer_t, set_value_t, _Sender, _Scheduler>
-    tag_invoke_result_t<transfer_t,
-                        __completion_scheduler_for<_Sender, set_value_t>,
-                        _Sender, _Scheduler>
-        operator()(_Sender&& __sndr, _Scheduler&& __sched) const
-        noexcept(nothrow_tag_invocable<
-                 transfer_t, __completion_scheduler_for<_Sender, set_value_t>,
-                 _Sender, _Scheduler>)
-    {
-        auto csch = get_completion_scheduler<set_value_t>(get_env(__sndr));
-        return tag_invoke(transfer_t{}, std::move(csch), (_Sender&&)__sndr,
-                          (_Scheduler&&)__sched);
-    }
-
-    template <sender _Sender, scheduler _Scheduler>
-        requires(!__tag_invocable_with_completion_scheduler<
-                    transfer_t, set_value_t, _Sender, _Scheduler>) &&
-                tag_invocable<transfer_t, _Sender, _Scheduler>
-    tag_invoke_result_t<transfer_t, _Sender, _Scheduler>
-        operator()(_Sender&& __sndr, _Scheduler&& __sched) const
-        noexcept(nothrow_tag_invocable<transfer_t, _Sender, _Scheduler>)
-    {
-        return tag_invoke(transfer_t{}, (_Sender&&)__sndr,
-                          (_Scheduler&&)__sched);
-    }
-
-    // NOT TO SPEC: permit non-typed senders:
-    template <sender _Sender, scheduler _Scheduler>
-        requires(!__tag_invocable_with_completion_scheduler<
-                    transfer_t, set_value_t, _Sender, _Scheduler>) &&
-                (!tag_invocable<transfer_t, _Sender, _Scheduler>)
     auto operator()(_Sender&& __sndr, _Scheduler&& __sched) const
     {
-        return schedule_from((_Scheduler&&)__sched, (_Sender&&)__sndr);
+        auto __domain = __get_early_domain(__sndr);
+        using _Env = __t<__environ<__id<__decay_t<_Scheduler>>>>;
+        return stdexec::transform_sender(
+            __domain, __make_sexpr<transfer_t>(_Env{{(_Scheduler&&)__sched}},
+                                               (_Sender&&)__sndr));
     }
 
     template <scheduler _Scheduler>
+    STDEXEC_ATTRIBUTE((always_inline)) //
     __binder_back<transfer_t, __decay_t<_Scheduler>>
         operator()(_Scheduler&& __sched) const
     {
         return {{}, {}, {(_Scheduler&&)__sched}};
     }
+
+    //////////////////////////////////////////////////////////////////////////////////////////////
+    using _Env = __0;
+    using _Sender = __1;
+    using __legacy_customizations_t = //
+        __types<tag_invoke_t(transfer_t,
+                             get_completion_scheduler_t<set_value_t>(
+                                 get_env_t(const _Sender&)),
+                             _Sender,
+                             get_completion_scheduler_t<set_value_t>(_Env)),
+                tag_invoke_t(transfer_t, _Sender,
+                             get_completion_scheduler_t<set_value_t>(_Env))>;
+
+    template <sender_expr_for<transfer_t> _Sender>
+    static decltype(auto) get_env(const _Sender& __sndr) noexcept
+    {
+        return __sexpr_apply(__sndr, __get_env_fn());
+    }
+
+    template <class _Env>
+    static auto __transform_sender_fn(const _Env&)
+    {
+        return [&]<class _Data, class _Child>(__ignore, _Data&& __data,
+                                              _Child&& __child) {
+            auto __sched = get_completion_scheduler<set_value_t>(__data);
+            return schedule_from(std::move(__sched), (_Child&&)__child);
+        };
+    }
+
+    template <class _Sender, class _Env>
+    static auto transform_sender(_Sender&& __sndr, const _Env& __env)
+    {
+        return __sexpr_apply((_Sender&&)__sndr, __transform_sender_fn(__env));
+    }
 };
 } // namespace __transfer
 
@@ -5844,6 +6759,215 @@
 inline constexpr transfer_t transfer{};
 
 /////////////////////////////////////////////////////////////////////////////
+// [execution.senders.transfer_just]
+namespace __transfer_just
+{
+// This is a helper for finding legacy cusutomizations of transfer_just.
+inline auto __transfer_just_tag_invoke()
+{
+    return []<class... _Ts>(
+               _Ts&&... __ts) -> tag_invoke_result_t<transfer_just_t, _Ts...> {
+        return tag_invoke(transfer_just, (_Ts&&)__ts...);
+    };
+}
+
+inline auto __make_env_fn() noexcept
+{
+    return []<class _Scheduler>(const _Scheduler& __sched,
+                                const auto&...) noexcept {
+        using _Env = __t<__schedule_from::__environ<__id<_Scheduler>>>;
+        return _Env{{__sched}};
+    };
+}
+
+inline auto __get_env_fn() noexcept
+{
+    return [](__ignore, const auto& __data) noexcept {
+        return __apply(__make_env_fn(), __data);
+    };
+}
+
+template <class _Env>
+auto __make_transform_fn(const _Env& __env)
+{
+    return [&]<class _Scheduler, class... _Values>(_Scheduler&& __sched,
+                                                   _Values&&... __vals) {
+        return transfer(just((_Values&&)__vals...), (_Scheduler&&)__sched);
+    };
+}
+
+template <class _Env>
+auto __transform_sender_fn(const _Env& __env)
+{
+    return [&]<class _Data>(__ignore, _Data&& __data) {
+        return __apply(__make_transform_fn(__env), (_Data&&)__data);
+    };
+}
+
+struct transfer_just_t
+{
+    using _Data = __0;
+    using __legacy_customizations_t = //
+        __types<__apply_t(decltype(__transfer_just_tag_invoke()), _Data)>;
+
+    template <scheduler _Scheduler, __movable_value... _Values>
+    auto operator()(_Scheduler&& __sched, _Values&&... __vals) const
+    {
+        auto __domain = query_or(get_domain, __sched, default_domain());
+        return stdexec::transform_sender(
+            __domain, __make_sexpr<transfer_just_t>(std::tuple{
+                          (_Scheduler&&)__sched, (_Values&&)__vals...}));
+    }
+
+    template <sender_expr_for<transfer_just_t> _Sender>
+    static auto get_env(const _Sender& __sndr) noexcept
+    {
+        return __sexpr_apply((_Sender&&)__sndr, __get_env_fn());
+    }
+
+    template <class _Sender, class _Env>
+    static auto transform_sender(_Sender&& __sndr, const _Env& __env)
+    {
+        return __sexpr_apply((_Sender&&)__sndr, __transform_sender_fn(__env));
+    }
+};
+} // namespace __transfer_just
+
+using __transfer_just::transfer_just_t;
+inline constexpr transfer_just_t transfer_just{};
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// __write adaptor
+namespace __write_
+{
+template <class _ReceiverId, class _Env>
+struct __operation_base
+{
+    using _Receiver = __t<_ReceiverId>;
+    _Receiver __rcvr_;
+    const _Env __env_;
+};
+
+inline constexpr auto __get_env = [](auto* __op) noexcept -> decltype(auto) {
+    return (__op->__env_);
+};
+
+template <class _ReceiverId, class _Env>
+using __receiver_t = //
+    __t<__detail::__receiver_with<&__operation_base<_ReceiverId, _Env>::__rcvr_,
+                                  __get_env>>;
+
+template <class _CvrefSenderId, class _ReceiverId, class _Env>
+struct __operation : __operation_base<_ReceiverId, _Env>
+{
+    using _CvrefSender = __cvref_t<_CvrefSenderId>;
+    using _Receiver = __t<_ReceiverId>;
+    using __base_t = __operation_base<_ReceiverId, _Env>;
+    using __receiver_t = __write_::__receiver_t<_ReceiverId, _Env>;
+    connect_result_t<_CvrefSender, __receiver_t> __state_;
+
+    __operation(_CvrefSender&& __sndr, _Receiver&& __rcvr, auto&& __env) :
+        __base_t{(_Receiver&&)__rcvr, (decltype(__env))__env},
+        __state_{
+            stdexec::connect((_CvrefSender&&)__sndr, __receiver_t{{}, this})}
+    {}
+
+    friend void tag_invoke(start_t, __operation& __self) noexcept
+    {
+        start(__self.__state_);
+    }
+};
+
+struct __write_t : __with_default_get_env<__write_t>
+{
+    template <sender _Sender, class... _Envs>
+    auto operator()(_Sender&& __sndr, _Envs... __envs) const
+    {
+        return __make_sexpr<__write_t>(__join_env(std::move(__envs)...),
+                                       (_Sender&&)__sndr);
+    }
+
+    template <class... _Envs>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+    auto operator()(_Envs... __envs) const -> __binder_back<__write_t, _Envs...>
+    {
+        return {{}, {}, {std::move(__envs)...}};
+    }
+
+    template <class _Env>
+    STDEXEC_ATTRIBUTE((always_inline))
+    static auto __transform_env_fn(_Env&& __env) noexcept
+    {
+        return [&](__ignore, const auto& __data, __ignore) noexcept {
+            return __join_env(__data, (_Env&&)__env);
+        };
+    }
+
+    template <sender_expr_for<__write_t> _Self, class _Env>
+    static auto transform_env(const _Self& __self, _Env&& __env) noexcept
+    {
+        return __sexpr_apply(__self, __transform_env_fn((_Env&&)__env));
+    }
+
+#if STDEXEC_FRIENDSHIP_IS_LEXICAL()
+  private:
+    template <class...>
+    friend struct stdexec::__sexpr;
+#endif
+
+    template <class _Self, class _Receiver>
+    using __receiver_t =
+        __write_::__receiver_t<__id<_Receiver>, __decay_t<__data_of<_Self>>>;
+
+    template <class _Self, class _Receiver>
+    using __operation_t =
+        __operation<__cvref_id<__child_of<_Self>>, __id<_Receiver>,
+                    __decay_t<__data_of<_Self>>>;
+
+    template <sender_expr_for<__write_t> _Self, receiver _Receiver>
+        requires sender_to<__child_of<_Self>, __receiver_t<_Self, _Receiver>>
+    static auto connect(_Self&& __self, _Receiver __rcvr)
+        -> __operation_t<_Self, _Receiver>
+    {
+        return __sexpr_apply((_Self&&)__self,
+                             [&]<class _Env, class _Child>(
+                                 __write_t, _Env&& __env, _Child&& __child) //
+                             -> __operation_t<_Self, _Receiver> {
+            return {(_Child&&)__child, (_Receiver&&)__rcvr, (_Env&&)__env};
+        });
+    }
+
+    template <sender_expr_for<__write_t> _Self, class _Env>
+    static auto get_completion_signatures(_Self&&, _Env&&)
+        -> stdexec::__completion_signatures_of_t<
+            __child_of<_Self>,
+            __env::__env_join_t<const __decay_t<__data_of<_Self>>&, _Env>>
+    {
+        return {};
+    }
+};
+} // namespace __write_
+
+using __write_::__write_t;
+inline constexpr __write_t __write{};
+
+namespace __detail
+{
+template <class _Scheduler>
+STDEXEC_ATTRIBUTE((always_inline))
+auto __mkenv_sched(_Scheduler __sched)
+{
+    auto __env = __join_env(__mkprop(__sched, get_scheduler),
+                            __mkprop(get_domain));
+
+    struct __env_t : decltype(__env)
+    {};
+
+    return __env_t{__env};
+}
+} // namespace __detail
+
+/////////////////////////////////////////////////////////////////////////////
 // [execution.senders.adaptors.on]
 namespace __on
 {
@@ -5851,39 +6975,29 @@
 struct __operation;
 
 template <class _SchedulerId, class _SenderId, class _ReceiverId>
-struct __receiver_ref
+struct __operation_base : __immovable
 {
     using _Scheduler = stdexec::__t<_SchedulerId>;
     using _Sender = stdexec::__t<_SenderId>;
     using _Receiver = stdexec::__t<_ReceiverId>;
 
-    struct __t : receiver_adaptor<__t>
-    {
-        using __id = __receiver_ref;
-        stdexec::__t<__operation<_SchedulerId, _SenderId, _ReceiverId>>*
-            __op_state_;
-
-        _Receiver&& base() && noexcept
-        {
-            return (_Receiver&&)__op_state_->__rcvr_;
-        }
-
-        const _Receiver& base() const& noexcept
-        {
-            return __op_state_->__rcvr_;
-        }
-
-        auto get_env() const noexcept
-            -> __make_env_t<env_of_t<_Receiver>,
-                            __with<get_scheduler_t, _Scheduler>>
-        {
-            return __make_env(
-                stdexec::get_env(this->base()),
-                __with_(get_scheduler, __op_state_->__scheduler_));
-        }
-    };
+    _Scheduler __scheduler_;
+    _Sender __sndr_;
+    _Receiver __rcvr_;
 };
 
+inline constexpr auto __sched_prop = [](auto* __op) noexcept {
+    return __mkprop(__op->__scheduler_, get_scheduler);
+};
+inline constexpr auto __domain_prop = [](auto*) noexcept {
+    return __mkprop(get_domain);
+};
+
+template <class _SchedulerId, class _SenderId, class _ReceiverId>
+using __receiver_ref_t = __t<__detail::__receiver_with<
+    &__operation_base<_SchedulerId, _SenderId, _ReceiverId>::__rcvr_,
+    __sched_prop, __domain_prop>>;
+
 template <class _SchedulerId, class _SenderId, class _ReceiverId>
 struct __receiver
 {
@@ -5895,7 +7009,7 @@
     {
         using __id = __receiver;
         using __receiver_ref_t =
-            stdexec::__t<__receiver_ref<_SchedulerId, _SenderId, _ReceiverId>>;
+            __on::__receiver_ref_t<_SchedulerId, _SenderId, _ReceiverId>;
         stdexec::__t<__operation<_SchedulerId, _SenderId, _ReceiverId>>*
             __op_state_;
 
@@ -5938,13 +7052,15 @@
     using _Sender = stdexec::__t<_SenderId>;
     using _Receiver = stdexec::__t<_ReceiverId>;
 
-    struct __t
+    struct __t : __operation_base<_SchedulerId, _SenderId, _ReceiverId>
     {
+        using _Base = __operation_base<_SchedulerId, _SenderId, _ReceiverId>;
         using __id = __operation;
         using __receiver_t =
             stdexec::__t<__receiver<_SchedulerId, _SenderId, _ReceiverId>>;
         using __receiver_ref_t =
-            stdexec::__t<__receiver_ref<_SchedulerId, _SenderId, _ReceiverId>>;
+            __on::__receiver_ref_t<_SchedulerId, _SenderId, _ReceiverId>;
+        using __schedule_sender_t = __result_of<schedule, _Scheduler>;
 
         friend void tag_invoke(start_t, __t& __self) noexcept
         {
@@ -5953,26 +7069,28 @@
 
         template <class _Sender2, class _Receiver2>
         __t(_Scheduler __sched, _Sender2&& __sndr, _Receiver2&& __rcvr) :
-            __scheduler_((_Scheduler&&)__sched), __sndr_((_Sender2&&)__sndr),
-            __rcvr_((_Receiver2&&)__rcvr),
+            _Base{{},
+                  (_Scheduler&&)__sched,
+                  (_Sender2&&)__sndr,
+                  (_Receiver2&&)__rcvr},
             __data_{std::in_place_index<0>, __conv{[this] {
-            return connect(schedule(__scheduler_), __receiver_t{{}, this});
+            return connect(schedule(this->__scheduler_),
+                           __receiver_t{{}, this});
         }}}
         {}
 
-        STDEXEC_IMMOVABLE(__t);
-
-        _Scheduler __scheduler_;
-        _Sender __sndr_;
-        _Receiver __rcvr_;
-        std::variant<
-            connect_result_t<schedule_result_t<_Scheduler>, __receiver_t>,
-            connect_result_t<_Sender, __receiver_ref_t>>
+        std::variant<connect_result_t<__schedule_sender_t, __receiver_t>,
+                     connect_result_t<_Sender, __receiver_ref_t>>
             __data_;
     };
 };
 
 template <class _SchedulerId, class _SenderId>
+struct __sender;
+
+struct on_t;
+
+template <class _SchedulerId, class _SenderId>
 struct __sender
 {
     using _Scheduler = stdexec::__t<_SchedulerId>;
@@ -5983,9 +7101,10 @@
         using __id = __sender;
         using is_sender = void;
 
+        using __schedule_sender_t = __result_of<schedule, _Scheduler>;
         template <class _ReceiverId>
         using __receiver_ref_t =
-            stdexec::__t<__receiver_ref<_SchedulerId, _SenderId, _ReceiverId>>;
+            __on::__receiver_ref_t<_SchedulerId, _SenderId, _ReceiverId>;
         template <class _ReceiverId>
         using __receiver_t =
             stdexec::__t<__receiver<_SchedulerId, _SenderId, _ReceiverId>>;
@@ -5999,7 +7118,7 @@
         template <__decays_to<__t> _Self, receiver _Receiver>
             requires constructible_from<_Sender,
                                         __copy_cvref_t<_Self, _Sender>> &&
-                     sender_to<schedule_result_t<_Scheduler>,
+                     sender_to<__schedule_sender_t,
                                __receiver_t<stdexec::__id<_Receiver>>> &&
                      sender_to<_Sender,
                                __receiver_ref_t<stdexec::__id<_Receiver>>>
@@ -6016,45 +7135,76 @@
             return get_env(__self.__sndr_);
         }
 
-        template <class...>
-        using __value_t = completion_signatures<>;
-
         template <__decays_to<__t> _Self, class _Env>
         friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
             -> __try_make_completion_signatures<
-                schedule_result_t<_Scheduler>, _Env,
+                __schedule_sender_t, _Env,
                 __try_make_completion_signatures<
                     __copy_cvref_t<_Self, _Sender>,
                     __make_env_t<_Env, __with<get_scheduler_t, _Scheduler>>,
                     completion_signatures<set_error_t(std::exception_ptr)>>,
-                __q<__value_t>>;
+                __mconst<completion_signatures<>>>
+        {
+            return {};
+        }
+
+        // BUGBUG better would be to port the `on` algorithm to __sexpr
+        template <class _Self, class _Fun, class _OnTag = on_t>
+        static auto apply(_Self&& __self, _Fun __fun)
+            -> __call_result_t<_Fun, _OnTag, __copy_cvref_t<_Self, _Scheduler>,
+                               __copy_cvref_t<_Self, _Sender>>
+        {
+            return ((_Fun&&)__fun)(_OnTag(), ((_Self&&)__self).__scheduler_,
+                                   ((_Self&&)__self).__sndr_);
+        }
     };
 };
 
-struct on_t
+struct on_t : __with_default_get_env<on_t>
 {
-    template <scheduler _Scheduler, sender _Sender>
-        requires tag_invocable<on_t, _Scheduler, _Sender>
-    auto operator()(_Scheduler&& __sched, _Sender&& __sndr) const
-        noexcept(nothrow_tag_invocable<on_t, _Scheduler, _Sender>)
-            -> tag_invoke_result_t<on_t, _Scheduler, _Sender>
-    {
-        return tag_invoke(*this, (_Scheduler&&)__sched, (_Sender&&)__sndr);
-    }
+    using _Sender = __1;
+    using _Scheduler = __0;
+    using __legacy_customizations_t =
+        __types<tag_invoke_t(on_t, _Scheduler, _Sender)>;
 
     template <scheduler _Scheduler, sender _Sender>
     auto operator()(_Scheduler&& __sched, _Sender&& __sndr) const
-        -> __t<__sender<stdexec::__id<__decay_t<_Scheduler>>,
-                        stdexec::__id<__decay_t<_Sender>>>>
     {
-        // connect-based customization will remove the need for this check
-        using __has_customizations =
-            __call_result_t<__has_algorithm_customizations_t, _Scheduler>;
-        static_assert(
-            !__has_customizations{},
-            "For now the default stdexec::on implementation doesn't support scheduling "
-            "onto schedulers that customize algorithms.");
-        return {(_Scheduler&&)__sched, (_Sender&&)__sndr};
+        auto __domain = query_or(get_domain, __sched, default_domain());
+        return stdexec::transform_sender(
+            __domain,
+            __make_sexpr<on_t>((_Scheduler&&)__sched, (_Sender&&)__sndr));
+    }
+
+    template <class _Scheduler, class _Sender>
+    using __sender_t = __t<__sender<stdexec::__id<__decay_t<_Scheduler>>,
+                                    stdexec::__id<__decay_t<_Sender>>>>;
+
+    template <class _Env>
+    STDEXEC_ATTRIBUTE((always_inline))
+    static auto __transform_env_fn(_Env&& __env) noexcept
+    {
+        return [&](__ignore, auto __sched, __ignore) noexcept {
+            return __join_env(__detail::__mkenv_sched(__sched), (_Env&&)__env);
+        };
+    }
+
+    template <class _Sender, class _Env>
+    static auto transform_env(const _Sender& __sndr, _Env&& __env) noexcept
+    {
+        return __sexpr_apply(__sndr, __transform_env_fn((_Env&&)__env));
+    }
+
+    template <class _Sender, class _Env>
+        requires __is_not_instance_of<__id<__decay_t<_Sender>>, __sender>
+    static auto transform_sender(_Sender&& __sndr, const _Env&)
+    {
+        return __sexpr_apply((_Sender&&)__sndr,
+                             []<class _Data, class _Child>(
+                                 __ignore, _Data&& __data, _Child&& __child) {
+            return __sender_t<_Data, _Child>{(_Data&&)__data,
+                                             (_Child&&)__child};
+        });
     }
 };
 } // namespace __on
@@ -6062,37 +7212,13 @@
 using __on::on_t;
 inline constexpr on_t on{};
 
-/////////////////////////////////////////////////////////////////////////////
-// [execution.senders.transfer_just]
-namespace __transfer_just
+// BUGBUG this will also be unnecessary when `on` returns a __sexpr
+namespace __detail
 {
-struct transfer_just_t
-{
-    template <scheduler _Scheduler, __movable_value... _Values>
-        requires tag_invocable<transfer_just_t, _Scheduler, _Values...> &&
-                 sender<tag_invoke_result_t<transfer_just_t, _Scheduler,
-                                            _Values...>>
-    auto operator()(_Scheduler&& __sched, _Values&&... __vals) const
-        noexcept(nothrow_tag_invocable<transfer_just_t, _Scheduler, _Values...>)
-            -> tag_invoke_result_t<transfer_just_t, _Scheduler, _Values...>
-    {
-        return tag_invoke(*this, (_Scheduler&&)__sched, (_Values&&)__vals...);
-    }
-
-    template <scheduler _Scheduler, __movable_value... _Values>
-        requires(!tag_invocable<transfer_just_t, _Scheduler, _Values...> ||
-                 !sender<tag_invoke_result_t<transfer_just_t, _Scheduler,
-                                             _Values...>>)
-    auto operator()(_Scheduler&& __sched, _Values&&... __vals) const
-        -> decltype(transfer(just((_Values&&)__vals...), (_Scheduler&&)__sched))
-    {
-        return transfer(just((_Values&&)__vals...), (_Scheduler&&)__sched);
-    }
-};
-} // namespace __transfer_just
-
-using __transfer_just::transfer_just_t;
-inline constexpr transfer_just_t transfer_just{};
+template <class _SchedulerId, class _SenderId>
+extern __mconst<__on::__sender<__t<_SchedulerId>, __name_of<__t<_SenderId>>>>
+    __name_of_v<__on::__sender<_SchedulerId, _SenderId>>;
+}
 
 /////////////////////////////////////////////////////////////////////////////
 // [execution.senders.adaptors.into_variant]
@@ -6152,79 +7278,72 @@
     };
 };
 
-template <class _SenderId>
-struct __sender
-{
-    using _Sender = stdexec::__t<_SenderId>;
+template <class _Sender, class _Env>
+using __variant_t = __try_value_types_of_t<_Sender, _Env>;
 
-    template <class _Env>
-    using __variant_t = __into_variant_result_t<_Sender, _Env>;
+template <class _Sender, class _Receiver>
+using __receiver_t = //
+    stdexec::__t<
+        __receiver<__id<_Receiver>, __variant_t<_Sender, env_of_t<_Receiver>>>>;
 
-    template <class _Receiver>
-    using __receiver_t = //
-        stdexec::__t<
-            __receiver<__id<_Receiver>, __variant_t<env_of_t<_Receiver>>>>;
+template <class _Variant>
+using __variant_completions =
+    completion_signatures<set_value_t(_Variant),
+                          set_error_t(std::exception_ptr)>;
 
-    struct __t
-    {
-        using __id = __sender;
-        using is_sender = void;
+template <class _Sender, class _Env>
+using __compl_sigs = //
+    __try_make_completion_signatures<
+        _Sender, _Env,
+        __meval<__variant_completions, __variant_t<_Sender, _Env>>,
+        __mconst<completion_signatures<>>>;
 
-        template <__decays_to<_Sender> _CvrefSender>
-        explicit __t(_CvrefSender&& __sndr) : __sndr_((_CvrefSender&&)__sndr)
-        {}
-
-      private:
-        template <class...>
-        using __value_t = completion_signatures<>;
-
-        template <class _Env>
-        using __compl_sigs = //
-            make_completion_signatures<
-                _Sender, _Env,
-                completion_signatures<set_value_t(__variant_t<_Env>),
-                                      set_error_t(std::exception_ptr)>,
-                __value_t>;
-
-        _Sender __sndr_;
-
-        template <receiver _Receiver>
-            requires sender_to<_Sender, __receiver_t<_Receiver>>
-        friend auto tag_invoke(connect_t, __t&& __self, _Receiver __rcvr) //
-            noexcept(__nothrow_connectable<_Sender, __receiver_t<_Receiver>>)
-                -> connect_result_t<_Sender, __receiver_t<_Receiver>>
-        {
-            return stdexec::connect(
-                (_Sender&&)__self.__sndr_,
-                __receiver_t<_Receiver>{(_Receiver&&)__rcvr});
-        }
-
-        friend auto tag_invoke(get_env_t, const __t& __self) noexcept
-            -> env_of_t<const _Sender&>
-        {
-            return get_env(__self.__sndr_);
-        }
-
-        template <class _Env>
-        friend auto tag_invoke(get_completion_signatures_t, __t&&, _Env&&) //
-            -> __compl_sigs<_Env>;
-    };
-};
-
-struct into_variant_t
+struct into_variant_t : __with_default_get_env<into_variant_t>
 {
     template <sender _Sender>
     auto operator()(_Sender&& __sndr) const
-        -> __t<__sender<stdexec::__id<__decay_t<_Sender>>>>
     {
-        return __t<__sender<stdexec::__id<__decay_t<_Sender>>>>{
-            (_Sender&&)__sndr};
+        auto __domain = __get_early_domain(__sndr);
+        return stdexec::transform_sender(
+            __domain, __make_sexpr<into_variant_t>(__(), std::move(__sndr)));
     }
 
+    STDEXEC_ATTRIBUTE((always_inline)) //
     auto operator()() const noexcept
     {
         return __binder_back<into_variant_t>{};
     }
+
+#if STDEXEC_FRIENDSHIP_IS_LEXICAL()
+  private:
+    template <class...>
+    friend struct stdexec::__sexpr;
+#endif
+
+    template <sender_expr_for<into_variant_t> _Self, receiver _Receiver>
+        requires sender_to<__child_of<_Self>,
+                           __receiver_t<__child_of<_Self>, _Receiver>>
+    static auto connect(_Self&& __self, _Receiver __rcvr) //
+        noexcept(__nothrow_connectable<
+                 __child_of<_Self>, __receiver_t<__child_of<_Self>, _Receiver>>)
+            -> connect_result_t<__child_of<_Self>,
+                                __receiver_t<__child_of<_Self>, _Receiver>>
+    {
+        return __sexpr_apply(
+            (_Self&&)__self,
+            [&]<class _Child>(__ignore, __ignore, _Child&& __child) {
+            return stdexec::connect(
+                (_Child&&)__child,
+                __receiver_t<_Child, _Receiver>{(_Receiver&&)__rcvr});
+        });
+    }
+
+    template <sender_expr_for<into_variant_t> _Self, class _Env>
+    static auto get_completion_signatures(_Self&&, _Env&&) //
+        -> __compl_sigs<__child_of<_Self>, _Env>
+    {
+        return {};
+    }
 };
 } // namespace __into_variant
 
@@ -6256,10 +7375,10 @@
 template <class _Env>
 auto __make_env(_Env&& __env, in_place_stop_source& __stop_source) noexcept
 {
-    return __env::__join_env(__env::__env_fn{[&](get_stop_token_t) noexcept {
+    return __join_env(__env::__env_fn{[&](get_stop_token_t) noexcept {
         return __stop_source.get_token();
     }},
-                             (_Env&&)__env);
+                      (_Env&&)__env);
 }
 
 template <class _Env>
@@ -6272,14 +7391,32 @@
 
 template <class _Sender, class _Env>
 concept __max1_sender = sender_in<_Sender, _Env> &&
-                        __valid<__value_types_of_t, _Sender, _Env,
-                                __mconst<int>, __msingle_or<void>>;
+                        __mvalid<__value_types_of_t, _Sender, _Env,
+                                 __mconst<int>, __msingle_or<void>>;
+
+template <
+    __mstring _Context = "In stdexec::when_all()..."__csz,
+    __mstring _Diagnostic =
+        "The given sender can complete successfully in more that one way. "
+        "Use stdexec::when_all_with_variant() instead."__csz>
+struct _INVALID_WHEN_ALL_ARGUMENT_;
+
+template <class _Sender, class _Env>
+using __too_many_value_completions_error =
+    __mexception<_INVALID_WHEN_ALL_ARGUMENT_<>, _WITH_SENDER_<_Sender>,
+                 _WITH_ENVIRONMENT_<_Env>>;
+
+template <class _Sender, class _Env, class _ValueTuple, class... _Rest>
+using __value_tuple_t =
+    __minvoke<__if_c<(0 == sizeof...(_Rest)), __mconst<_ValueTuple>,
+                     __q<__too_many_value_completions_error>>,
+              _Sender, _Env>;
 
 template <class _Env, class _Sender>
 using __single_values_of_t = //
     __try_value_types_of_t<_Sender, _Env,
                            __transform<__q<__decay_rvalue_ref>, __q<__types>>,
-                           __q<__msingle>>;
+                           __mbind_front_q<__value_tuple_t, _Sender, _Env>>;
 
 template <class _Env, class... _Senders>
 using __set_values_sig_t = //
@@ -6291,20 +7428,17 @@
 using __all_nothrow_decay_copyable =
     __mbool<(__nothrow_decay_copyable<_Args> && ...)>;
 
-template <class _Env, class... _SenderIds>
+template <class _Env, class... _Senders>
 using __all_value_and_error_args_nothrow_decay_copyable = //
-    __mand<                                               //
-        __mand<__try_value_types_of_t<__t<_SenderIds>, _Env,
-                                      __q<__all_nothrow_decay_copyable>,
-                                      __q<__mand>>...>,
-        __mand<__try_error_types_of_t<__t<_SenderIds>, _Env,
-                                      __q<__all_nothrow_decay_copyable>>...>>;
+    __mand<__compl_sigs::__maybe_for_all_sigs<
+        __completion_signatures_of_t<_Senders, _Env>,
+        __q<__all_nothrow_decay_copyable>, __q<__mand>>...>;
 
 template <class _Env, class... _Senders>
 using __completions_t = //
     __concat_completion_signatures_t<
-        __if<__all_value_and_error_args_nothrow_decay_copyable<
-                 _Env, __id<_Senders>...>,
+        __if<__all_value_and_error_args_nothrow_decay_copyable<_Env,
+                                                               _Senders...>,
              completion_signatures<set_stopped_t()>,
              completion_signatures<set_stopped_t(),
                                    set_error_t(std::exception_ptr&&)>>,
@@ -6354,10 +7488,10 @@
 template <class _Receiver, class _ValuesTuple>
 void __set_values(_Receiver& __rcvr, _ValuesTuple& __values) noexcept
 {
-    std::apply(
+    __apply(
         [&](auto&... __opt_vals) noexcept -> void {
-        std::apply(__complete_fn{set_value, __rcvr},
-                   std::tuple_cat(std::apply(__tie_fn{}, *__opt_vals)...));
+        __apply(__complete_fn{set_value, __rcvr},
+                std::tuple_cat(__apply(__tie_fn{}, *__opt_vals)...));
     },
         __values);
 }
@@ -6410,7 +7544,7 @@
     // Could be non-atomic here and atomic_ref everywhere except __completion_fn
     std::atomic<__state_t> __state_{__started};
     _ErrorsVariant __errors_{};
-    STDEXEC_NO_UNIQUE_ADDRESS _ValuesTuple __values_{};
+    STDEXEC_ATTRIBUTE((no_unique_address)) _ValuesTuple __values_{};
     std::optional<typename stop_token_of_t<
         env_of_t<_Receiver>&>::template callback_type<__on_stop_requested>>
         __on_stop_{};
@@ -6548,8 +7682,6 @@
 template <class _Env, __max1_sender<__env_t<_Env>>... _Senders>
 struct __traits_
 {
-    using __completions = __completions_t<__env_t<_Env>, _Senders...>;
-
     // tuple<optional<tuple<Vs1...>>, optional<tuple<Vs2...>>, ...>
     using __values_tuple = //
         __minvoke<__with_default<
@@ -6566,8 +7698,8 @@
                   error_types_of_t<_Senders, __env_t<_Env>, __types>...>;
 
     using __errors_variant = //
-        __if<__all_value_and_error_args_nothrow_decay_copyable<
-                 _Env, __id<_Senders>...>,
+        __if<__all_value_and_error_args_nothrow_decay_copyable<_Env,
+                                                               _Senders...>,
              __error_types,
              __minvoke<__push_back_unique<__q<std::variant>>, __error_types,
                        std::exception_ptr>>;
@@ -6578,7 +7710,6 @@
 struct __traits : __traits_<env_of_t<_Receiver>, _Senders...>
 {
     using _Traits = __traits_<env_of_t<_Receiver>, _Senders...>;
-    using typename _Traits::__completions;
     using typename _Traits::__errors_variant;
     using typename _Traits::__values_tuple;
 
@@ -6610,12 +7741,11 @@
                          _SenderIds...>::template __op_states_tuple<>;
 
 template <class _Cvref, class _ReceiverId, class... _SenderIds>
-    requires __valid<__op_states_tuple_ex, _Cvref, _ReceiverId, _SenderIds...>
+    requires __mvalid<__op_states_tuple_ex, _Cvref, _ReceiverId, _SenderIds...>
 struct __operation
 {
     using _Receiver = stdexec::__t<_ReceiverId>;
     using _Traits = __traits_ex<_Cvref, _ReceiverId, _SenderIds...>;
-    using _Indices = std::index_sequence_for<_SenderIds...>;
 
     using __operation_base_t = typename _Traits::__operation_base;
     using __op_states_tuple_t =
@@ -6628,21 +7758,15 @@
     {
         using __id = __operation;
 
-        template <class _SendersTuple, std::size_t... _Is>
-        __t(_SendersTuple&& __sndrs, _Receiver __rcvr,
-            std::index_sequence<_Is...>) :
+        template <std::size_t... _Is, class... _Senders>
+        __t(_Receiver __rcvr, __indices<_Is...>, _Senders&&... __sndrs) :
             __operation_base_t{{}, (_Receiver&&)__rcvr, {sizeof...(_Is)}},
-            __op_states_{__conv{[&__sndrs, this]() {
-            return stdexec::connect(std::get<_Is>((_SendersTuple&&)__sndrs),
+            __op_states_{__conv{[&, this]() {
+            return stdexec::connect((_Senders&&)__sndrs,
                                     __receiver_t<_Is>{this});
         }}...}
         {}
 
-        template <class _SendersTuple>
-        __t(_SendersTuple&& __sndrs, _Receiver __rcvr) :
-            __t((_SendersTuple&&)__sndrs, (_Receiver&&)__rcvr, _Indices{})
-        {}
-
         friend void tag_invoke(start_t, __t& __self) noexcept
         {
             // register stop callback:
@@ -6657,7 +7781,7 @@
             }
             else
             {
-                std::apply(
+                __apply(
                     [](auto&... __child_ops) noexcept -> void {
                     (stdexec::start(__child_ops), ...);
                 },
@@ -6673,176 +7797,221 @@
     };
 };
 
-template <class _From, class _ToId>
-using __cvref_id = __copy_cvref_t<_From, __t<_ToId>>;
+struct _INVALID_ARGUMENTS_TO_WHEN_ALL_
+{};
 
-template <class _Indices, class... _SenderIds>
-struct __sender;
-
-template <std::size_t... _Indices, class... _SenderIds>
-struct __sender<std::index_sequence<_Indices...>, _SenderIds...>
+struct when_all_t : __domain::__get_env_common_domain<when_all_t>
 {
-    template <class _Self, class _Env>
-    using __completions_t =
-        typename __traits_<_Env,
-                           __cvref_id<_Self, _SenderIds>...>::__completions;
+    // Used by the default_domain to find legacy customizations:
+    using _Sender = __1;
+    using __legacy_customizations_t = //
+        __types<tag_invoke_t(when_all_t, _Sender...)>;
 
-    template <class _Self, class _Receiver, std::size_t _Index>
-    using __receiver_t =
-        typename __traits<_Receiver, __cvref_id<_Self, _SenderIds>...>::
-            template __receiver<_Index>;
+    // TODO: improve diagnostic when senders have different domains
+    template <sender... _Senders>
+        requires __domain::__has_common_domain<_Senders...>
+    auto operator()(_Senders&&... __sndrs) const
+    {
+        auto __domain = __domain::__common_domain_t<_Senders...>();
+        return stdexec::transform_sender(
+            __domain, __make_sexpr<when_all_t>(__(), (_Senders&&)__sndrs...));
+    }
+
+#if STDEXEC_FRIENDSHIP_IS_LEXICAL()
+  private:
+    template <class...>
+    friend struct stdexec::__sexpr;
+#endif
+
+    template <class _Self, class _Env>
+    using __error = __mexception<_INVALID_ARGUMENTS_TO_WHEN_ALL_,
+                                 __children_of<_Self, __q<_WITH_SENDERS_>>,
+                                 _WITH_ENVIRONMENT_<_Env>>;
+
+    template <class _Self, class _Env>
+    using __completions = //
+        __children_of<_Self, __mbind_front_q<__completions_t, __env_t<_Env>>>;
+
+    template <sender_expr_for<when_all_t> _Self, class _Env>
+    static auto get_completion_signatures(_Self&&, _Env&&)
+    {
+        return __minvoke<__mtry_catch<__q<__completions>, __q<__error>>, _Self,
+                         _Env>();
+    }
+
+    template <class _Receiver, class _Indices>
+    struct __connect_fn;
+
+    template <class _Receiver, std::size_t... _Indices>
+    struct __connect_fn<_Receiver, __indices<_Indices...>>
+    {
+        _Receiver* __rcvr_;
+
+        template <std::size_t _Index, class... _Senders>
+        using __receiver_t =
+            typename __traits<_Receiver,
+                              _Senders...>::template __receiver<_Index>;
+
+        template <class... _Senders>
+            requires(sender_to<_Senders, __receiver_t<_Indices, _Senders...>> &&
+                     ...)
+        auto operator()(__ignore, __ignore, _Senders&&... __sndrs) const
+        {
+            using _Cvref = __copy_cvref_fn<__mfront<_Senders..., int>>;
+            using __operation_t =
+                __t<__operation<_Cvref, __id<_Receiver>,
+                                __id<__decay_t<_Senders>>...>>;
+            return __operation_t{(_Receiver&&)*__rcvr_,
+                                 __indices<_Indices...>(),
+                                 (_Senders&&)__sndrs...};
+        }
+    };
 
     template <class _Self, class _Receiver>
-    using __operation_t =
-        stdexec::__t<__operation<__copy_cvref_fn<_Self>,
-                                 stdexec::__id<_Receiver>, _SenderIds...>>;
+    using __connect_fn_for = //
+        __connect_fn<_Receiver, __make_indices<__nbr_children_of<_Self>>>;
 
-    struct __t
+    template <sender_expr_for<when_all_t> _Self, class _Receiver>
+        requires __callable<__sexpr_apply_t, _Self,
+                            __connect_fn_for<_Self, _Receiver>>
+    static auto connect(_Self&& __self, _Receiver __rcvr)
     {
-        using __id = __sender;
-        using is_sender = void;
-
-        template <class... _Sndrs>
-        explicit(sizeof...(_Sndrs) == 1) __t(_Sndrs&&... __sndrs) :
-            __sndrs_((_Sndrs&&)__sndrs...)
-        {}
-
-      private:
-        template <__decays_to<__t> _Self, receiver _Receiver>
-            requires(sender_to<__cvref_id<_Self, _SenderIds>,
-                               __receiver_t<_Self, _Receiver, _Indices>> &&
-                     ...)
-        friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr)
-            -> __operation_t<_Self, _Receiver>
-        {
-            return {((_Self&&)__self).__sndrs_, (_Receiver&&)__rcvr};
-        }
-
-        template <__decays_to<__t> _Self, class _Env>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
-            -> dependent_completion_signatures<_Env>;
-        template <__decays_to<__t> _Self, class _Env>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
-            -> __completions_t<_Self, _Env>
-            requires true;
-
-        friend empty_env tag_invoke(get_env_t, const __t&) noexcept
-        {
-            return {};
-        }
-
-        std::tuple<stdexec::__t<_SenderIds>...> __sndrs_;
-    };
-};
-
-template <class _Sender>
-using __into_variant_result_t = decltype(into_variant(__declval<_Sender>()));
-
-struct when_all_t
-{
-    template <class... _Senders>
-    using __sender_t = __t<__sender<std::index_sequence_for<_Senders...>,
-                                    __id<__decay_t<_Senders>>...>>;
-
-    template <sender... _Senders>
-        requires tag_invocable<when_all_t, _Senders...> &&
-                 sender<tag_invoke_result_t<when_all_t, _Senders...>>
-    auto operator()(_Senders&&... __sndrs) const
-        noexcept(nothrow_tag_invocable<when_all_t, _Senders...>)
-            -> tag_invoke_result_t<when_all_t, _Senders...>
-    {
-        return tag_invoke(*this, (_Senders&&)__sndrs...);
-    }
-
-    template <sender... _Senders>
-        requires(!tag_invocable<when_all_t, _Senders...>) &&
-                sender<__sender_t<_Senders...>>
-    __sender_t<_Senders...> operator()(_Senders&&... __sndrs) const
-    {
-        return __sender_t<_Senders...>{(_Senders&&)__sndrs...};
+        using __connect_fn = __connect_fn_for<_Self, _Receiver>;
+        return __sexpr_apply((_Self&&)__self, __connect_fn{&__rcvr});
     }
 };
 
-struct when_all_with_variant_t
+struct when_all_with_variant_t :
+    __domain::__get_env_common_domain<when_all_with_variant_t>
 {
-    template <sender... _Senders>
-        requires tag_invocable<when_all_with_variant_t, _Senders...> &&
-                 sender<
-                     tag_invoke_result_t<when_all_with_variant_t, _Senders...>>
-    auto operator()(_Senders&&... __sndrs) const
-        noexcept(nothrow_tag_invocable<when_all_with_variant_t, _Senders...>)
-            -> tag_invoke_result_t<when_all_with_variant_t, _Senders...>
-    {
-        return tag_invoke(*this, (_Senders&&)__sndrs...);
-    }
+    using _Sender = __1;
+    using __legacy_customizations_t = //
+        __types<tag_invoke_t(when_all_with_variant_t, _Sender...)>;
 
     template <sender... _Senders>
-        requires(!tag_invocable<when_all_with_variant_t, _Senders...>) &&
-                (__callable<into_variant_t, _Senders> && ...)
+        requires __domain::__has_common_domain<_Senders...>
     auto operator()(_Senders&&... __sndrs) const
     {
-        return when_all_t{}(into_variant((_Senders&&)__sndrs)...);
+        auto __domain = __domain::__common_domain_t<_Senders...>();
+        return stdexec::transform_sender(__domain,
+                                         __make_sexpr<when_all_with_variant_t>(
+                                             __(), (_Senders&&)__sndrs...));
+    }
+
+    template <class _Sender, class _Env>
+    static auto transform_sender(_Sender&& __sndr, const _Env& __env)
+    {
+        // transform the when_all_with_variant into a regular when_all (looking
+        // for early when_all customizations), then transform it again to look
+        // for late customizations.
+        return __sexpr_apply(
+            (_Sender&&)__sndr,
+            [&]<class... _Child>(__ignore, __ignore, _Child&&... __child) {
+            return when_all_t()(into_variant((_Child&&)__child)...);
+        });
     }
 };
 
 struct transfer_when_all_t
 {
-    template <scheduler _Sched, sender... _Senders>
-        requires tag_invocable<transfer_when_all_t, _Sched, _Senders...> &&
-                 sender<tag_invoke_result_t<transfer_when_all_t, _Sched,
-                                            _Senders...>>
-    auto operator()(_Sched&& __sched, _Senders&&... __sndrs) const noexcept(
-        nothrow_tag_invocable<transfer_when_all_t, _Sched, _Senders...>)
-        -> tag_invoke_result_t<transfer_when_all_t, _Sched, _Senders...>
+    using _Env = __0;
+    using _Sender = __1;
+    using __legacy_customizations_t = //
+        __types<tag_invoke_t(
+            transfer_when_all_t,
+            get_completion_scheduler_t<set_value_t>(const _Env&), _Sender...)>;
+
+    template <scheduler _Scheduler, sender... _Senders>
+        requires __domain::__has_common_domain<_Senders...>
+    auto operator()(_Scheduler&& __sched, _Senders&&... __sndrs) const
     {
-        return tag_invoke(*this, (_Sched&&)__sched, (_Senders&&)__sndrs...);
+        using _Env =
+            __t<__schedule_from::__environ<__id<__decay_t<_Scheduler>>>>;
+        auto __domain = query_or(get_domain, __sched, default_domain());
+        return stdexec::transform_sender(
+            __domain,
+            __make_sexpr<transfer_when_all_t>(_Env{{(_Scheduler&&)__sched}},
+                                              (_Senders&&)__sndrs...));
     }
 
-    template <scheduler _Sched, sender... _Senders>
-        requires((!tag_invocable<transfer_when_all_t, _Sched, _Senders...>) ||
-                 (!sender<tag_invoke_result_t<transfer_when_all_t, _Sched,
-                                              _Senders...>>))
-    auto operator()(_Sched&& __sched, _Senders&&... __sndrs) const
+    template <sender_expr_for<transfer_when_all_t> _Sender>
+    static __data_of<const _Sender&> get_env(const _Sender& __self) noexcept
     {
-        return transfer(when_all_t{}((_Senders&&)__sndrs...),
-                        (_Sched&&)__sched);
+        return __sexpr_apply(__self, __detail::__get_data());
+    }
+
+    template <class _Sender, class _Env>
+    static auto transform_sender(_Sender&& __sndr, const _Env& __env)
+    {
+        // transform the transfer_when_all into a regular transform | when_all
+        // (looking for early customizations), then transform it again to look
+        // for late customizations.
+        return __sexpr_apply(
+            (_Sender&&)__sndr,
+            [&]<class _Data, class... _Child>(__ignore, _Data&& __data,
+                                              _Child&&... __child) {
+            return transfer(when_all_t()((_Child&&)__child...),
+                            get_completion_scheduler<set_value_t>(__data));
+        });
     }
 };
 
 struct transfer_when_all_with_variant_t
 {
-    template <scheduler _Sched, sender... _Senders>
-        requires tag_invocable<transfer_when_all_with_variant_t, _Sched,
-                               _Senders...> &&
-                 sender<tag_invoke_result_t<transfer_when_all_with_variant_t,
-                                            _Sched, _Senders...>>
-    auto operator()(_Sched&& __sched, _Senders&&... __sndrs) const
-        noexcept(nothrow_tag_invocable<transfer_when_all_with_variant_t, _Sched,
-                                       _Senders...>)
-            -> tag_invoke_result_t<transfer_when_all_with_variant_t, _Sched,
-                                   _Senders...>
+    using _Env = __0;
+    using _Sender = __1;
+    using __legacy_customizations_t = //
+        __types<tag_invoke_t(
+            transfer_when_all_with_variant_t,
+            get_completion_scheduler_t<set_value_t>(const _Env&), _Sender...)>;
+
+    template <scheduler _Scheduler, sender... _Senders>
+        requires __domain::__has_common_domain<_Senders...>
+    auto operator()(_Scheduler&& __sched, _Senders&&... __sndrs) const
     {
-        return tag_invoke(*this, (_Sched&&)__sched, (_Senders&&)__sndrs...);
+        using _Env =
+            __t<__schedule_from::__environ<__id<__decay_t<_Scheduler>>>>;
+        auto __domain = query_or(get_domain, __sched, default_domain());
+        return stdexec::transform_sender(
+            __domain,
+            __make_sexpr<transfer_when_all_with_variant_t>(
+                _Env{{(_Scheduler&&)__sched}}, (_Senders&&)__sndrs...));
     }
 
-    template <scheduler _Sched, sender... _Senders>
-        requires(!tag_invocable<transfer_when_all_with_variant_t, _Sched,
-                                _Senders...>) &&
-                (__callable<into_variant_t, _Senders> && ...)
-    auto operator()(_Sched&& __sched, _Senders&&... __sndrs) const
+    template <sender_expr_for<transfer_when_all_with_variant_t> _Sender>
+    static __data_of<const _Sender&> get_env(const _Sender& __self) noexcept
     {
-        return transfer_when_all_t{}((_Sched&&)__sched,
-                                     into_variant((_Senders&&)__sndrs)...);
+        return __sexpr_apply(__self, __detail::__get_data());
+    }
+
+    template <class _Sender, class _Env>
+    static auto transform_sender(_Sender&& __sndr, const _Env& __env)
+    {
+        // transform the transfer_when_allwith_variant into regular
+        // transform_when_all and into_variant calls/ (looking for early
+        // customizations), then transform it again to look for late
+        // customizations.
+        return __sexpr_apply(
+            (_Sender&&)__sndr,
+            [&]<class _Data, class... _Child>(__ignore, _Data&& __data,
+                                              _Child&&... __child) {
+            return transfer_when_all_t()(
+                get_completion_scheduler<set_value_t>((_Data&&)__data),
+                into_variant((_Child&&)__child)...);
+        });
     }
 };
 } // namespace __when_all
 
 using __when_all::when_all_t;
 inline constexpr when_all_t when_all{};
+
 using __when_all::when_all_with_variant_t;
 inline constexpr when_all_with_variant_t when_all_with_variant{};
+
 using __when_all::transfer_when_all_t;
 inline constexpr transfer_when_all_t transfer_when_all{};
+
 using __when_all::transfer_when_all_with_variant_t;
 inline constexpr transfer_when_all_with_variant_t
     transfer_when_all_with_variant{};
@@ -6850,6 +8019,15 @@
 namespace __read
 {
 template <class _Tag, class _ReceiverId>
+using __result_t = __call_result_t<_Tag, env_of_t<stdexec::__t<_ReceiverId>>>;
+
+template <class _Tag, class _ReceiverId>
+concept __nothrow_t =
+    __nothrow_callable<_Tag, env_of_t<stdexec::__t<_ReceiverId>>>;
+
+// NOT TO SPEC: if the query returns a value, store the value in the operation
+// state and pass an rvalue reference to it.
+template <class _Tag, class _ReceiverId>
 struct __operation
 {
     using _Receiver = stdexec::__t<_ReceiverId>;
@@ -6858,22 +8036,66 @@
     {
         using __id = __operation;
         _Receiver __rcvr_;
+        std::optional<__result_t<_Tag, _ReceiverId>> __result_;
+
+        friend void tag_invoke(start_t, __t& __self) noexcept
+        {
+            constexpr bool _Nothrow =
+                __nothrow_callable<_Tag, env_of_t<_Receiver>>;
+            auto __query =
+                [&]() noexcept(_Nothrow) -> __result_t<_Tag, _ReceiverId>&& {
+                __self.__result_.emplace(__conv{[&]() noexcept(_Nothrow) {
+                    return _Tag()(get_env(__self.__rcvr_));
+                }});
+                return std::move(*__self.__result_);
+            };
+            stdexec::__set_value_invoke(std::move(__self.__rcvr_), __query);
+        }
+    };
+};
+
+// if the query returns a reference type, pass it straight through to the
+// receiver.
+template <class _Tag, class _ReceiverId>
+    requires std::same_as<__result_t<_Tag, _ReceiverId>&&,
+                          __result_t<_Tag, _ReceiverId>>
+struct __operation<_Tag, _ReceiverId>
+{
+    using _Receiver = stdexec::__t<_ReceiverId>;
+
+    struct __t : __immovable
+    {
+        using __id = __operation;
+        _Receiver __rcvr_;
 
         friend void tag_invoke(start_t, __t& __self) noexcept
         {
-            try
-            {
-                auto __env = get_env(__self.__rcvr_);
-                set_value(std::move(__self.__rcvr_), _Tag{}(__env));
-            }
-            catch (...)
-            {
-                set_error(std::move(__self.__rcvr_), std::current_exception());
-            }
+            stdexec::__set_value_invoke(std::move(__self.__rcvr_), _Tag(),
+                                        get_env(__self.__rcvr_));
         }
     };
 };
 
+inline constexpr __mstring __query_failed_diag =
+    "The current execution environment doesn't have a value for the given query."__csz;
+
+template <class _Tag>
+struct _WITH_QUERY_;
+
+template <class _Tag, class _Env>
+using __query_failed_error = //
+    __mexception<            //
+        _NOT_CALLABLE_<"In stdexec::read()..."__csz, __query_failed_diag>,
+        _WITH_QUERY_<_Tag>, _WITH_ENVIRONMENT_<_Env>>;
+
+template <class _Tag, class _Env>
+    requires __callable<_Tag, _Env>
+using __completions_t = //
+    __if_c<__nothrow_callable<_Tag, _Env>,
+           completion_signatures<set_value_t(__call_result_t<_Tag, _Env>)>,
+           completion_signatures<set_value_t(__call_result_t<_Tag, _Env>),
+                                 set_error_t(std::exception_ptr)>>;
+
 template <class _Tag>
 struct __sender
 {
@@ -6882,10 +8104,9 @@
     using is_sender = void;
 
     template <class _Env>
-        requires __callable<_Tag, _Env>
-    using __completions_t = //
-        completion_signatures<set_value_t(__call_result_t<_Tag, _Env>),
-                              set_error_t(std::exception_ptr)>;
+    using __completions_t = __minvoke<
+        __mtry_catch_q<__read::__completions_t, __q<__query_failed_error>>,
+        _Tag, _Env>;
 
     template <class _Receiver>
         requires receiver_of<_Receiver, __completions_t<env_of_t<_Receiver>>>
@@ -6898,10 +8119,10 @@
 
     template <class _Env>
     friend auto tag_invoke(get_completion_signatures_t, __sender, _Env&&)
-        -> dependent_completion_signatures<_Env>;
-    template <__none_of<no_env> _Env>
-    friend auto tag_invoke(get_completion_signatures_t, __sender, _Env&&)
-        -> __completions_t<_Env>;
+        -> __completions_t<_Env>
+    {
+        return {};
+    }
 
     friend empty_env tag_invoke(get_env_t, const __t&) noexcept
     {
@@ -6983,13 +8204,179 @@
 } // namespace __queries
 
 /////////////////////////////////////////////////////////////////////////////
+// [execution.senders.adaptors.on]
+namespace __on_v2
+{
+inline constexpr __mstring __on_context =
+    "In stdexec::on(Scheduler, Sender)..."__csz;
+inline constexpr __mstring __no_scheduler_diag =
+    "stdexec::on() requires a scheduler to transition back to."__csz;
+inline constexpr __mstring __no_scheduler_details =
+    "The provided environment lacks a value for the get_scheduler() query."__csz;
+
+template <__mstring _Context = __on_context,
+          __mstring _Diagnostic = __no_scheduler_diag,
+          __mstring _Details = __no_scheduler_details>
+struct _CANNOT_RESTORE_EXECUTION_CONTEXT_AFTER_ON_
+{};
+
+struct on_t;
+
+STDEXEC_PRAGMA_PUSH()
+STDEXEC_PRAGMA_IGNORE_GNU("-Wunused-local-typedefs")
+
+struct __no_scheduler_in_environment
+{
+    // Issue a custom diagnostic if the environment doesn't provide a scheduler.
+    template <class _Sender, class _Env>
+    static auto transform_sender(_Sender&&, const _Env&)
+    {
+        struct __no_scheduler_in_environment
+        {
+            using is_sender = void;
+            using completion_signatures = //
+                __mexception<_CANNOT_RESTORE_EXECUTION_CONTEXT_AFTER_ON_<>,
+                             _WITH_SENDER_<_Sender>, _WITH_ENVIRONMENT_<_Env>>;
+        };
+
+        return __no_scheduler_in_environment{};
+    }
+};
+
+STDEXEC_PRAGMA_POP()
+
+template <class _Ty, class = __name_of<__decay_t<_Ty>>>
+struct __always
+{
+    _Ty __val_;
+
+    _Ty operator()() noexcept
+    {
+        return static_cast<_Ty&&>(__val_);
+    }
+};
+
+template <class _Ty>
+__always(_Ty) -> __always<_Ty>;
+
+struct on_t : __with_default_get_env<on_t>, __no_scheduler_in_environment
+{
+    template <scheduler _Scheduler, sender _Sender>
+    auto operator()(_Scheduler&& __sched, _Sender&& __sndr) const
+    {
+        // BUGBUG __get_early_domain, or get_domain(__sched), or ...?
+        auto __domain = __get_early_domain(__sndr);
+        return stdexec::transform_sender(
+            __domain,
+            __make_sexpr<on_t>((_Scheduler&&)__sched, (_Sender&&)__sndr));
+    }
+
+    template <class _Env>
+    STDEXEC_ATTRIBUTE((always_inline))
+    static auto __transform_env_fn(_Env&& __env) noexcept
+    {
+        return [&](__ignore, auto __sched, __ignore) noexcept {
+            return __join_env(__detail::__mkenv_sched(__sched), (_Env&&)__env);
+        };
+    }
+
+    template <class _Sender, class _Env>
+    static auto transform_env(const _Sender& __sndr, _Env&& __env) noexcept
+    {
+        return __sexpr_apply(__sndr, __transform_env_fn((_Env&&)__env));
+    }
+
+    using __no_scheduler_in_environment::transform_sender;
+
+    template <class _Sender, class _Env>
+        requires __callable<get_scheduler_t, const _Env&>
+    static auto transform_sender(_Sender&& __sndr, const _Env& __env)
+    {
+        return __sexpr_apply(
+            (_Sender&&)__sndr,
+            [&]<class _Scheduler, class _Child>(__ignore, _Scheduler __sched,
+                                                _Child&& __child) {
+            auto __old = get_scheduler(__env);
+            return transfer(let_value(transfer_just(std::move(__sched)),
+                                      __always{(_Child&&)__child}),
+                            std::move(__old));
+        });
+    }
+};
+
+template <class _Scheduler, class _Closure>
+struct __continue_on_data
+{
+    _Scheduler __sched_;
+    _Closure __clsur_;
+};
+template <class _Scheduler, class _Closure>
+__continue_on_data(_Scheduler, _Closure)
+    -> __continue_on_data<_Scheduler, _Closure>;
+
+struct continue_on_t :
+    __with_default_get_env<continue_on_t>,
+    __no_scheduler_in_environment
+{
+    template <sender _Sender, scheduler _Scheduler,
+              __sender_adaptor_closure_for<_Sender> _Closure>
+    auto operator()(_Sender&& __sndr, _Scheduler&& __sched,
+                    _Closure&& __clsur) const
+    {
+        auto __domain = __get_early_domain(__sndr);
+        return stdexec::transform_sender(
+            __domain,
+            __make_sexpr<continue_on_t>(
+                __continue_on_data{(_Scheduler&&)__sched, (_Closure&&)__clsur},
+                (_Sender&&)__sndr));
+    }
+
+    template <scheduler _Scheduler, __sender_adaptor_closure _Closure>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+    auto operator()(_Scheduler&& __sched, _Closure&& __clsur) const
+        -> __binder_back<continue_on_t, __decay_t<_Scheduler>,
+                         __decay_t<_Closure>>
+    {
+        return {{}, {}, {(_Scheduler&&)__sched, (_Closure&&)__clsur}};
+    }
+
+    using __no_scheduler_in_environment::transform_sender;
+
+    template <class _Sender, class _Env>
+        requires __callable<get_scheduler_t, const _Env&>
+    static auto transform_sender(_Sender&& __sndr, const _Env& __env)
+    {
+        auto __old = get_scheduler(__env);
+        return __sexpr_apply((_Sender&&)__sndr,
+                             [&]<class _Data, class _Child>(
+                                 __ignore, _Data&& __data, _Child&& __child) {
+            auto&& [__sched, __clsur] = (_Data&&)__data;
+            using _Closure = decltype(__clsur);
+            return __write(transfer(((_Closure&&)__clsur)(transfer(
+                                        __write((_Child&&)__child,
+                                                __detail::__mkenv_sched(__old)),
+                                        __sched)),
+                                    __old),
+                           __detail::__mkenv_sched(__sched));
+        });
+    }
+};
+} // namespace __on_v2
+
+namespace v2
+{
+using __on_v2::on_t;
+inline constexpr on_t on{};
+
+using __on_v2::continue_on_t;
+inline constexpr continue_on_t continue_on{};
+} // namespace v2
+
+/////////////////////////////////////////////////////////////////////////////
 // [execution.senders.consumers.sync_wait]
 // [execution.senders.consumers.sync_wait_with_variant]
 namespace __sync_wait
 {
-template <class _Sender>
-using __into_variant_result_t = decltype(into_variant(__declval<_Sender>()));
-
 inline auto __make_env(run_loop& __loop) noexcept
 {
     return __env::__env_fn{
@@ -6999,21 +8386,26 @@
     }};
 }
 
-using __env = decltype(__sync_wait::__make_env(__declval<run_loop&>()));
+struct __env : __result_of<__make_env, run_loop&>
+{
+    __env();
+
+    __env(run_loop& __loop) noexcept :
+        __result_of<__make_env, run_loop&>{__sync_wait::__make_env(__loop)}
+    {}
+};
 
 // What should sync_wait(just_stopped()) return?
-template <sender_in<__env> _Sender, class _Continuation>
-using __sync_wait_result_impl = __value_types_of_t<
-    _Sender, __env, __transform<__q<__decay_t>, _Continuation>, __q<__msingle>>;
+template <class _Sender, class _Continuation>
+using __sync_wait_result_impl = //
+    __try_value_types_of_t<_Sender, __env,
+                           __transform<__q<__decay_t>, _Continuation>,
+                           __q<__msingle>>;
 
 template <class _Sender>
 using __sync_wait_result_t =
     __mtry_eval<__sync_wait_result_impl, _Sender, __q<std::tuple>>;
 
-template <class _Sender>
-using __sync_wait_with_variant_result_t =
-    __sync_wait_result_t<__into_variant_result_t<_Sender>>;
-
 template <class... _Values>
 struct __state
 {
@@ -7075,35 +8467,150 @@
 
         friend __env tag_invoke(get_env_t, const __t& __rcvr) noexcept
         {
-            return __sync_wait::__make_env(*__rcvr.__loop_);
+            return __env(*__rcvr.__loop_);
         }
     };
 };
 
 template <class _Sender>
-using __into_variant_result_t = decltype(into_variant(__declval<_Sender>()));
-
-struct sync_wait_t;
-
-using _Sender = __0;
-using __cust_sigs =
-    __types<tag_invoke_t(sync_wait_t,
-                         get_completion_scheduler_t<set_value_t>(
-                             get_env_t(const _Sender&)),
-                         _Sender),
-            tag_invoke_t(sync_wait_t, _Sender)>;
-
-template <class _Sender>
-inline constexpr bool __is_sync_wait_customized =
-    __minvocable<__which<__cust_sigs>, _Sender>;
-
-template <class _Sender>
 using __receiver_t = __t<__sync_wait_result_impl<_Sender, __q<__receiver>>>;
 
-struct __default_impl
+// These are for hiding the metaprogramming in diagnostics
+template <class _Sender>
+struct __sync_receiver_for
 {
-    template <class _Sender>
+    using __t = __receiver_t<_Sender>;
+};
+template <class _Sender>
+using __sync_receiver_for_t = __t<__sync_receiver_for<_Sender>>;
+
+template <class _Sender>
+struct __value_tuple_for
+{
+    using __t = __sync_wait_result_t<_Sender>;
+};
+template <class _Sender>
+using __value_tuple_for_t = __t<__value_tuple_for<_Sender>>;
+
+template <class _Sender>
+struct __variant_for
+{
+    using __t = __sync_wait_result_t<__result_of<into_variant, _Sender>>;
+};
+template <class _Sender>
+using __variant_for_t = __t<__variant_for<_Sender>>;
+
+inline constexpr __mstring __sync_wait_context_diag = //
+    "In stdexec::sync_wait()..."__csz;
+inline constexpr __mstring __too_many_successful_completions_diag =
+    "The argument to stdexec::sync_wait() is a sender that can complete successfully in more "
+    "than one way. Use stdexec::sync_wait_with_variant() instead."__csz;
+
+template <__mstring _Context, __mstring _Diagnostic>
+struct _INVALID_ARGUMENT_TO_SYNC_WAIT_;
+
+template <__mstring _Diagnostic>
+using __invalid_argument_to_sync_wait =
+    _INVALID_ARGUMENT_TO_SYNC_WAIT_<__sync_wait_context_diag, _Diagnostic>;
+
+template <__mstring _Diagnostic, class _Sender, class _Env = __env>
+using __sync_wait_error =
+    __mexception<__invalid_argument_to_sync_wait<_Diagnostic>,
+                 _WITH_SENDER_<_Sender>, _WITH_ENVIRONMENT_<_Env>>;
+
+template <class _Sender, class>
+using __too_many_successful_completions_error =
+    __sync_wait_error<__too_many_successful_completions_diag, _Sender>;
+
+template <class _Sender>
+concept __valid_sync_wait_argument =
+    __ok<__minvoke<__mtry_catch_q<__single_value_variant_sender_t,
+                                  __q<__too_many_successful_completions_error>>,
+                   _Sender, __env>>;
+
+#if STDEXEC_NVHPC()
+// It requires some hoop-jumping to get the NVHPC compiler to report a
+// meaningful diagnostic for SFINAE failures.
+template <class _Sender>
+auto __diagnose_error()
+{
+    if constexpr (!sender_in<_Sender, __env>)
+    {
+        using _Completions = __completion_signatures_of_t<_Sender, __env>;
+        if constexpr (!__ok<_Completions>)
+        {
+            return _Completions();
+        }
+        else
+        {
+            constexpr __mstring __diag =
+                "The stdexec::sender_in<Sender, Environment> concept check has failed."__csz;
+            return __sync_wait_error<__diag, _Sender>();
+        }
+    }
+    else if constexpr (!__valid_sync_wait_argument<_Sender>)
+    {
+        return __sync_wait_error<__too_many_successful_completions_diag,
+                                 _Sender>();
+    }
+    else if constexpr (!sender_to<_Sender, __sync_receiver_for_t<_Sender>>)
+    {
+        constexpr __mstring __diag =
+            "Failed to connect the given sender to sync_wait's internal receiver. "
+            "The stdexec::connect(Sender, Receiver) expression is ill-formed."__csz;
+        return __sync_wait_error<__diag, _Sender>();
+    }
+    else
+    {
+        constexpr __mstring __diag = "Unknown concept check failure."__csz;
+        return __sync_wait_error<__diag, _Sender>();
+    }
+    STDEXEC_UNREACHABLE();
+}
+
+template <class _Sender>
+using __error_description_t =
+    decltype(__sync_wait::__diagnose_error<_Sender>());
+#endif
+
+////////////////////////////////////////////////////////////////////////////
+// [execution.senders.consumers.sync_wait]
+struct sync_wait_t
+{
+    template <sender_in<__env> _Sender>
+        requires __valid_sync_wait_argument<_Sender> &&
+                 __has_implementation_for<sync_wait_t,
+                                          __early_domain_of_t<_Sender>, _Sender>
     auto operator()(_Sender&& __sndr) const
+        -> std::optional<__value_tuple_for_t<_Sender>>
+    {
+        using _SD = __early_domain_of_t<_Sender>;
+        constexpr bool __has_custom_impl =
+            __callable<apply_sender_t, _SD, sync_wait_t, _Sender>;
+        using _Domain = __if_c<__has_custom_impl, _SD, default_domain>;
+        return stdexec::apply_sender(_Domain(), *this, (_Sender&&)__sndr);
+    }
+
+#if STDEXEC_NVHPC()
+    // This is needed to get sensible diagnostics from nvc++
+    template <class _Sender, class _Error = __error_description_t<_Sender>>
+    auto operator()(_Sender&&, [[maybe_unused]] _Error __diagnostic = {}) const
+        -> std::optional<std::tuple<int>> = delete;
+#endif
+
+    using _Sender = __0;
+    using __legacy_customizations_t = __types<
+        // For legacy reasons:
+        tag_invoke_t(
+            sync_wait_t,
+            get_completion_scheduler_t<set_value_t>(get_env_t(const _Sender&)),
+            _Sender),
+        tag_invoke_t(sync_wait_t, _Sender)>;
+
+    // The default implementation goes here:
+    template <class _Sender>
+        requires sender_to<_Sender, __sync_receiver_for_t<_Sender>>
+    auto apply_sender(_Sender&& __sndr) const
         -> std::optional<__sync_wait_result_t<_Sender>>
     {
         using state_t = __sync_wait_result_impl<_Sender, __q<__state>>;
@@ -7129,108 +8636,55 @@
     }
 };
 
-template <class _Sender>
-using __dispatcher_for =
-    __make_dispatcher<__cust_sigs, __mconst<__default_impl>, _Sender>;
-
-// These are for hiding the metaprogramming in diagnostics
-template <class _Sender>
-struct __sync_receiver_for
-{
-    using __t = __receiver_t<_Sender>;
-};
-template <class _Sender>
-using __sync_receiver_for_t = __t<__sync_receiver_for<_Sender>>;
-
-template <class _Sender>
-struct __value_tuple_for
-{
-    using __t = __sync_wait_result_t<_Sender>;
-};
-template <class _Sender>
-using __value_tuple_for_t = __t<__value_tuple_for<_Sender>>;
-
-////////////////////////////////////////////////////////////////////////////
-// [execution.senders.consumers.sync_wait]
-struct sync_wait_t
-{
-    template <sender_in<__env> _Sender>
-        requires __satisfies<__single_value_variant_sender<_Sender, __env>> &&
-                 (sender_to<_Sender, __sync_receiver_for_t<_Sender>> ||
-                  __is_sync_wait_customized<_Sender>)
-    auto operator()(_Sender&& __sndr) const
-        -> std::optional<__value_tuple_for_t<_Sender>>
-    {
-        // The selected implementation should return void
-        return __dispatcher_for<_Sender>{}((_Sender&&)__sndr);
-    }
-};
-
 ////////////////////////////////////////////////////////////////////////////
 // [execution.senders.consumers.sync_wait_with_variant]
 struct sync_wait_with_variant_t
 {
-    template <sender_in<__env> _Sender>
-        requires __tag_invocable_with_completion_scheduler<
-            sync_wait_with_variant_t, set_value_t, _Sender>
-    tag_invoke_result_t<sync_wait_with_variant_t,
-                        __completion_scheduler_for<_Sender, set_value_t>,
-                        _Sender>
-        operator()(_Sender&& __sndr) const
-        noexcept(nothrow_tag_invocable<
-                 sync_wait_with_variant_t,
-                 __completion_scheduler_for<_Sender, set_value_t>, _Sender>)
-    {
-        static_assert(
-            std::is_same_v<
-                tag_invoke_result_t<
-                    sync_wait_with_variant_t,
-                    __completion_scheduler_for<_Sender, set_value_t>, _Sender>,
-                std::optional<__sync_wait_with_variant_result_t<_Sender>>>,
-            "The type of tag_invoke(sync_wait_with_variant, get_completion_scheduler, S) "
-            "must be sync-wait-with-variant-type<S, sync-wait-env>");
+    struct __impl;
 
-        auto __sched = get_completion_scheduler<set_value_t>(get_env(__sndr));
-        return tag_invoke(sync_wait_with_variant_t{}, std::move(__sched),
-                          (_Sender&&)__sndr);
+    template <sender_in<__env> _Sender>
+        requires __callable<apply_sender_t, __early_domain_of_t<_Sender>,
+                            sync_wait_with_variant_t, _Sender>
+    auto operator()(_Sender&& __sndr) const
+        -> std::optional<__variant_for_t<_Sender>>
+    {
+        auto __domain = __get_early_domain(__sndr);
+        return stdexec::apply_sender(__domain, *this, (_Sender&&)__sndr);
     }
 
-    template <sender_in<__env> _Sender>
-        requires(!__tag_invocable_with_completion_scheduler<
-                    sync_wait_with_variant_t, set_value_t, _Sender>) &&
-                tag_invocable<sync_wait_with_variant_t, _Sender>
-    tag_invoke_result_t<sync_wait_with_variant_t, _Sender>
-        operator()(_Sender&& __sndr) const
-        noexcept(nothrow_tag_invocable<sync_wait_with_variant_t, _Sender>)
-    {
-        static_assert(
-            std::is_same_v<
-                tag_invoke_result_t<sync_wait_with_variant_t, _Sender>,
-                std::optional<__sync_wait_with_variant_result_t<_Sender>>>,
-            "The type of tag_invoke(sync_wait_with_variant, S) "
-            "must be sync-wait-with-variant-type<S, sync-wait-env>");
+#if STDEXEC_NVHPC()
+    template <class _Sender, class _Error = __error_description_t<
+                                 __result_of<into_variant, _Sender>>>
+    auto operator()(_Sender&&, [[maybe_unused]] _Error __diagnostic = {}) const
+        -> std::optional<std::tuple<std::variant<std::tuple<>>>> = delete;
+#endif
 
-        return tag_invoke(sync_wait_with_variant_t{}, (_Sender&&)__sndr);
-    }
+    using _Sender = __0;
+    using __legacy_customizations_t = __types<
+        // For legacy reasons:
+        tag_invoke_t(
+            sync_wait_with_variant_t,
+            get_completion_scheduler_t<set_value_t>(get_env_t(const _Sender&)),
+            _Sender),
+        tag_invoke_t(sync_wait_with_variant_t, _Sender)>;
 
-    template <sender_in<__env> _Sender>
-        requires(!__tag_invocable_with_completion_scheduler<
-                    sync_wait_with_variant_t, set_value_t, _Sender>) &&
-                (!tag_invocable<sync_wait_with_variant_t, _Sender>) &&
-                invocable<sync_wait_t, __into_variant_result_t<_Sender>>
-    std::optional<__sync_wait_with_variant_result_t<_Sender>>
-        operator()(_Sender&& __sndr) const
+    template <class _Sender>
+        requires __callable<sync_wait_t, __result_of<into_variant, _Sender>>
+    auto apply_sender(_Sender&& __sndr) const
+        -> std::optional<__variant_for_t<_Sender>>
     {
-        return sync_wait_t{}(into_variant((_Sender&&)__sndr));
+        return sync_wait_t()(into_variant((_Sender&&)__sndr));
     }
 };
 } // namespace __sync_wait
 
 using __sync_wait::sync_wait_t;
 inline constexpr sync_wait_t sync_wait{};
+
 using __sync_wait::sync_wait_with_variant_t;
 inline constexpr sync_wait_with_variant_t sync_wait_with_variant{};
 
+//////////////////////////////////////////////////////////////////////////////////////////////////
 struct __ignore_sender
 {
     using is_sender = void;
@@ -7245,14 +8699,135 @@
 {};
 
 template <class _Sender>
-struct _WITH_SENDER_
-{};
-
-template <class _Sender>
 using __bad_pipe_sink_t =
     __mexception<_CANNOT_PIPE_INTO_A_SENDER_<>, _WITH_SENDER_<_Sender>>;
 } // namespace stdexec
 
+#if STDEXEC_MSVC()
+namespace stdexec
+{
+// MSVCBUG
+// https://developercommunity.visualstudio.com/t/Incorrect-codegen-in-await_suspend-aroun/10454102
+
+// MSVC incorrectly allocates the return buffer for await_suspend calls within
+// the suspended coroutine frame. When the suspended coroutine is destroyed
+// within await_suspend, the continuation coroutine handle is not only used
+// after free, but also overwritten by the debug malloc implementation when NRVO
+// is in play.
+
+// This workaround delays the destruction of the suspended coroutine by wrapping
+// the continuation in another coroutine which destroys the former and transfers
+// execution to the original continuation.
+
+// The wrapping coroutine is thread-local and is reused within the thread for
+// each destroy-and-continue sequence. The wrapping coroutine itself is
+// destroyed at thread exit.
+
+namespace __destroy_and_continue_msvc
+{
+struct __task
+{
+    struct promise_type
+    {
+        __task get_return_object() noexcept
+        {
+            return {
+                __coro::coroutine_handle<promise_type>::from_promise(*this)};
+        }
+
+        static std::suspend_never initial_suspend() noexcept
+        {
+            return {};
+        }
+
+        static std::suspend_never final_suspend() noexcept
+        {
+            STDEXEC_ASSERT(!"Should never get here");
+            return {};
+        }
+
+        static void return_void() noexcept
+        {
+            STDEXEC_ASSERT(!"Should never get here");
+        }
+
+        static void unhandled_exception() noexcept
+        {
+            STDEXEC_ASSERT(!"Should never get here");
+        }
+    };
+
+    __coro::coroutine_handle<> __coro_;
+};
+
+struct __continue_t
+{
+    static constexpr bool await_ready() noexcept
+    {
+        return false;
+    }
+
+    __coro::coroutine_handle<>
+        await_suspend(__coro::coroutine_handle<>) noexcept
+    {
+        return __continue_;
+    }
+
+    static void await_resume() noexcept {}
+
+    __coro::coroutine_handle<> __continue_;
+};
+
+struct __context
+{
+    __coro::coroutine_handle<> __destroy_;
+    __coro::coroutine_handle<> __continue_;
+};
+
+inline __task __co_impl(__context& __c)
+{
+    while (true)
+    {
+        co_await __continue_t{__c.__continue_};
+        __c.__destroy_.destroy();
+    }
+}
+
+struct __context_and_coro
+{
+    __context_and_coro()
+    {
+        __context_.__continue_ = __coro::noop_coroutine();
+        __coro_ = __co_impl(__context_).__coro_;
+    }
+
+    ~__context_and_coro()
+    {
+        __coro_.destroy();
+    }
+
+    __context __context_;
+    __coro::coroutine_handle<> __coro_;
+};
+
+inline __coro::coroutine_handle<> __impl(__coro::coroutine_handle<> __destroy,
+                                         __coro::coroutine_handle<> __continue)
+{
+    static thread_local __context_and_coro __c;
+    __c.__context_.__destroy_ = __destroy;
+    __c.__context_.__continue_ = __continue;
+    return __c.__coro_;
+}
+} // namespace __destroy_and_continue_msvc
+} // namespace stdexec
+
+#define STDEXEC_DESTROY_AND_CONTINUE(__destroy, __continue)                    \
+    (::stdexec::__destroy_and_continue_msvc::__impl(__destroy, __continue))
+#else
+#define STDEXEC_DESTROY_AND_CONTINUE(__destroy, __continue)                    \
+    (__destroy.destroy(), __continue)
+#endif
+
 // For issuing a meaningful diagnostic for the erroneous `snd1 | snd2`.
 template <stdexec::sender _Sender>
     requires stdexec::__ok<stdexec::__bad_pipe_sink_t<_Sender>>
@@ -7261,8 +8836,4 @@
 
 #include "__detail/__p2300.hpp"
 
-#ifdef __EDG__
-#pragma diagnostic pop
-#endif
-
 STDEXEC_PRAGMA_POP()
diff --git a/include/sdbusplus/async/stdexec/functional.hpp b/include/sdbusplus/async/stdexec/functional.hpp
index 0f76474..b0bcc0f 100644
--- a/include/sdbusplus/async/stdexec/functional.hpp
+++ b/include/sdbusplus/async/stdexec/functional.hpp
@@ -20,9 +20,7 @@
 #include "concepts.hpp"
 
 #include <functional>
-
-// A std::declval that doesn't instantiate templates:
-#define _DECLVAL(...) ((static_cast<__VA_ARGS__ (*)() noexcept>(0))())
+#include <tuple>
 
 namespace stdexec::__std_concepts
 {
@@ -44,41 +42,334 @@
 
 namespace stdexec
 {
-template <class _Fun, class... _As>
-concept __nothrow_invocable =  //
-    invocable<_Fun, _As...> && //
-    requires(_Fun&& __f, _As&&... __as) {
-        {
-            std::invoke((_Fun&&)__f, (_As&&)__as...)
-        } noexcept;
-    };
-
-struct __first
-{
-    template <class _First, class _Second>
-    constexpr _First&& operator()(_First&& __first, _Second&&) const noexcept
-    {
-        return (_First&&)__first;
-    }
-};
-
 template <auto _Fun>
-struct __fun_c_t
+struct __function_constant
 {
     using _FunT = decltype(_Fun);
 
     template <class... _Args>
         requires __callable<_FunT, _Args...>
-    auto operator()(_Args&&... __args) const
+    STDEXEC_ATTRIBUTE((always_inline)) //
+        auto
+        operator()(_Args&&... __args) const
         noexcept(noexcept(_Fun((_Args&&)__args...)))
-            -> __call_result_t<_FunT, _Args...>
+            -> decltype(_Fun((_Args&&)__args...))
     {
         return _Fun((_Args&&)__args...);
     }
 };
 
+template <class _Ty, class _Cl, _Ty _Cl::*_MemPtr>
+struct __function_constant<_MemPtr>
+{
+    using _FunT = _Ty _Cl::*;
+
+    template <class _Arg>
+        requires requires(_Arg&& __arg) { ((_Arg&&)__arg).*_MemPtr; }
+    STDEXEC_ATTRIBUTE((always_inline)) //
+        constexpr auto
+        operator()(_Arg&& __arg) const noexcept
+        -> decltype((((_Arg&&)__arg).*_MemPtr))
+    {
+        return ((_Arg&&)__arg).*_MemPtr;
+    }
+};
+
 template <auto _Fun>
-inline constexpr __fun_c_t<_Fun> __fun_c{};
+inline constexpr __function_constant<_Fun> __function_constant_v{};
+
+template <class _Fun0, class _Fun1>
+struct __composed
+{
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Fun0 __t0_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Fun1 __t1_;
+
+    template <class... _Ts>
+        requires __callable<_Fun1, _Ts...> &&
+                 __callable<_Fun0, __call_result_t<_Fun1, _Ts...>>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+        __call_result_t<_Fun0, __call_result_t<_Fun1, _Ts...>>
+        operator()(_Ts&&... __ts) &&
+    {
+        return ((_Fun0&&)__t0_)(((_Fun1&&)__t1_)((_Ts&&)__ts...));
+    }
+
+    template <class... _Ts>
+        requires __callable<const _Fun1&, _Ts...> &&
+                 __callable<const _Fun0&, __call_result_t<const _Fun1&, _Ts...>>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+        __call_result_t<_Fun0, __call_result_t<_Fun1, _Ts...>>
+        operator()(_Ts&&... __ts) const&
+    {
+        return __t0_(__t1_((_Ts&&)__ts...));
+    }
+};
+
+inline constexpr struct __compose_t
+{
+    template <class _Fun0, class _Fun1>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+    __composed<_Fun0, _Fun1> operator()(_Fun0 __fun0, _Fun1 __fun1) const
+    {
+        return {(_Fun0&&)__fun0, (_Fun1&&)__fun1};
+    }
+} __compose{};
+
+namespace __invoke_
+{
+template <class>
+inline constexpr bool __is_refwrap = false;
+template <class _Up>
+inline constexpr bool __is_refwrap<std::reference_wrapper<_Up>> = true;
+
+struct __funobj
+{
+    template <class _Fun, class... _Args>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+    constexpr auto operator()(_Fun&& __fun, _Args&&... __args) const
+        noexcept(noexcept(((_Fun&&)__fun)((_Args&&)__args...)))
+            -> decltype(((_Fun&&)__fun)((_Args&&)__args...))
+    {
+        return ((_Fun&&)__fun)((_Args&&)__args...);
+    }
+};
+
+struct __memfn
+{
+    template <class _Memptr, class _Ty, class... _Args>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+    constexpr auto operator()(_Memptr __mem_ptr, _Ty&& __ty,
+                              _Args&&... __args) const
+        noexcept(noexcept((((_Ty&&)__ty).*__mem_ptr)((_Args&&)__args...)))
+            -> decltype((((_Ty&&)__ty).*__mem_ptr)((_Args&&)__args...))
+    {
+        return (((_Ty&&)__ty).*__mem_ptr)((_Args&&)__args...);
+    }
+};
+
+struct __memfn_refwrap
+{
+    template <class _Memptr, class _Ty, class... _Args>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+    constexpr auto operator()(_Memptr __mem_ptr, _Ty __ty,
+                              _Args&&... __args) const
+        noexcept(noexcept((__ty.get().*__mem_ptr)((_Args&&)__args...)))
+            -> decltype((__ty.get().*__mem_ptr)((_Args&&)__args...))
+    {
+        return (__ty.get().*__mem_ptr)((_Args&&)__args...);
+    }
+};
+
+struct __memfn_smartptr
+{
+    template <class _Memptr, class _Ty, class... _Args>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+    constexpr auto operator()(_Memptr __mem_ptr, _Ty&& __ty,
+                              _Args&&... __args) const
+        noexcept(noexcept(((*(_Ty&&)__ty).*__mem_ptr)((_Args&&)__args...)))
+            -> decltype(((*(_Ty&&)__ty).*__mem_ptr)((_Args&&)__args...))
+    {
+        return ((*(_Ty&&)__ty).*__mem_ptr)((_Args&&)__args...);
+    }
+};
+
+struct __memobj
+{
+    template <class _Mbr, class _Class, class _Ty>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+    constexpr auto operator()(_Mbr _Class::*__mem_ptr,
+                              _Ty&& __ty) const noexcept
+        -> decltype((((_Ty&&)__ty).*__mem_ptr))
+    {
+        return (((_Ty&&)__ty).*__mem_ptr);
+    }
+};
+
+struct __memobj_refwrap
+{
+    template <class _Mbr, class _Class, class _Ty>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+    constexpr auto operator()(_Mbr _Class::*__mem_ptr, _Ty __ty) const noexcept
+        -> decltype((__ty.get().*__mem_ptr))
+    {
+        return (__ty.get().*__mem_ptr);
+    }
+};
+
+struct __memobj_smartptr
+{
+    template <class _Mbr, class _Class, class _Ty>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+    constexpr auto operator()(_Mbr _Class::*__mem_ptr,
+                              _Ty&& __ty) const noexcept
+        -> decltype(((*(_Ty&&)__ty).*__mem_ptr))
+    {
+        return ((*(_Ty&&)__ty).*__mem_ptr);
+    }
+};
+
+__funobj __invoke_selector(__ignore, __ignore) noexcept;
+
+template <class _Mbr, class _Class, class _Ty>
+auto __invoke_selector(_Mbr _Class::*, const _Ty&) noexcept
+{
+    if constexpr (STDEXEC_IS_CONST(_Mbr) || STDEXEC_IS_CONST(const _Mbr))
+    {
+        // member function ptr case
+        if constexpr (STDEXEC_IS_BASE_OF(_Class, _Ty))
+        {
+            return __memobj{};
+        }
+        else if constexpr (__is_refwrap<_Ty>)
+        {
+            return __memobj_refwrap{};
+        }
+        else
+        {
+            return __memobj_smartptr{};
+        }
+    }
+    else
+    {
+        // member object ptr case
+        if constexpr (STDEXEC_IS_BASE_OF(_Class, _Ty))
+        {
+            return __memfn{};
+        }
+        else if constexpr (__is_refwrap<_Ty>)
+        {
+            return __memfn_refwrap{};
+        }
+        else
+        {
+            return __memfn_smartptr{};
+        }
+    }
+}
+
+struct __invoke_t
+{
+    template <class _Fun>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+    constexpr auto operator()(_Fun&& __fun) const
+        noexcept(noexcept(((_Fun&&)__fun)())) -> decltype(((_Fun&&)__fun)())
+    {
+        return ((_Fun&&)__fun)();
+    }
+
+    template <class _Fun, class _Ty, class... _Args>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+    constexpr auto operator()(_Fun&& __fun, _Ty&& __ty, _Args&&... __args) const
+        noexcept(noexcept(__invoke_selector(__fun, __ty)((_Fun&&)__fun,
+                                                         (_Ty&&)__ty,
+                                                         (_Args&&)__args...)))
+            -> decltype(__invoke_selector(__fun, __ty)((_Fun&&)__fun,
+                                                       (_Ty&&)__ty,
+                                                       (_Args&&)__args...))
+    {
+        return decltype(__invoke_selector(__fun, __ty))()(
+            (_Fun&&)__fun, (_Ty&&)__ty, (_Args&&)__args...);
+    }
+};
+} // namespace __invoke_
+
+inline constexpr __invoke_::__invoke_t __invoke{};
+
+template <class _Fun, class... _As>
+concept __invocable = //
+    requires(_Fun&& __f, _As&&... __as) {
+        __invoke((_Fun&&)__f, (_As&&)__as...);
+    };
+
+template <class _Fun, class... _As>
+concept __nothrow_invocable =    //
+    __invocable<_Fun, _As...> && //
+    requires(_Fun&& __f, _As&&... __as) {
+        {
+            __invoke((_Fun&&)__f, (_As&&)__as...)
+        } noexcept;
+    };
+
+template <class _Fun, class... _As>
+using __invoke_result_t = //
+    decltype(__invoke(__declval<_Fun>(), __declval<_As>()...));
+
+namespace __apply_
+{
+using std::get;
+
+template <std::size_t... _Is, class _Fn, class _Tup>
+STDEXEC_ATTRIBUTE((always_inline)) //
+constexpr auto __impl(__indices<_Is...>, _Fn&& __fn, _Tup&& __tup) noexcept(
+    noexcept(__invoke((_Fn&&)__fn, get<_Is>((_Tup&&)__tup)...)))
+    -> decltype(__invoke((_Fn&&)__fn, get<_Is>((_Tup&&)__tup)...))
+{
+    return __invoke((_Fn&&)__fn, get<_Is>((_Tup&&)__tup)...);
+}
+
+template <class _Tup>
+using __tuple_indices =
+    __make_indices<std::tuple_size<std::remove_cvref_t<_Tup>>::value>;
+
+template <class _Fn, class _Tup>
+using __result_t = decltype(__apply_::__impl(
+    __tuple_indices<_Tup>(), __declval<_Fn>(), __declval<_Tup>()));
+} // namespace __apply_
+
+template <class _Fn, class _Tup>
+concept __applicable = __mvalid<__apply_::__result_t, _Fn, _Tup>;
+
+template <class _Fn, class _Tup>
+concept __nothrow_applicable = __applicable<_Fn, _Tup> //
+    && noexcept(__apply_::__impl(__apply_::__tuple_indices<_Tup>(),
+                                 __declval<_Fn>(), __declval<_Tup>()));
+
+template <class _Fn, class _Tup>
+    requires __applicable<_Fn, _Tup>
+using __apply_result_t = __apply_::__result_t<_Fn, _Tup>;
+
+struct __apply_t
+{
+    template <class _Fn, class _Tup>
+        requires __applicable<_Fn, _Tup>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+        constexpr auto
+        operator()(_Fn&& __fn, _Tup&& __tup) const
+        noexcept(__nothrow_applicable<_Fn, _Tup>) -> __apply_result_t<_Fn, _Tup>
+    {
+        return __apply_::__impl(__apply_::__tuple_indices<_Tup>(), (_Fn&&)__fn,
+                                (_Tup&&)__tup);
+    }
+};
+
+inline constexpr __apply_t __apply{};
+
+template <class _Tag, class _Ty>
+struct __field
+{
+    STDEXEC_ATTRIBUTE((always_inline)) //
+    _Ty operator()(_Tag) const noexcept(__nothrow_decay_copyable<const _Ty&>)
+    {
+        return __t_;
+    }
+
+    _Ty __t_;
+};
+
+template <class _Tag>
+struct __mkfield_
+{
+    template <class _Ty>
+    STDEXEC_ATTRIBUTE((always_inline)) //
+    __field<_Tag, __decay_t<_Ty>> operator()(_Ty&& __ty) const
+        noexcept(__nothrow_decay_copyable<_Ty>)
+    {
+        return {(_Ty&&)__ty};
+    }
+};
+
+template <class _Tag>
+inline constexpr __mkfield_<_Tag> __mkfield{};
 
 // [func.tag_invoke], tag_invoke
 namespace __tag_invoke
@@ -131,17 +422,25 @@
 {
     template <class _Tag, class... _Args>
         requires tag_invocable<_Tag, _Args...>
-    constexpr auto operator()(_Tag __tag, _Args&&... __args) const
+    STDEXEC_ATTRIBUTE((always_inline)) constexpr auto
+        operator()(_Tag __tag, _Args&&... __args) const
         noexcept(nothrow_tag_invocable<_Tag, _Args...>)
             -> tag_invoke_result_t<_Tag, _Args...>
     {
         return tag_invoke((_Tag&&)__tag, (_Args&&)__args...);
     }
 };
+
 } // namespace __tag_invoke
 
 using __tag_invoke::tag_invoke_t;
+
+namespace __ti
+{
 inline constexpr tag_invoke_t tag_invoke{};
+}
+
+using namespace __ti;
 
 template <auto& _Tag>
 using tag_t = __decay_t<decltype(_Tag)>;
diff --git a/include/sdbusplus/async/stdexec/import b/include/sdbusplus/async/stdexec/import
index 4ba6a80..df69427 100755
--- a/include/sdbusplus/async/stdexec/import
+++ b/include/sdbusplus/async/stdexec/import
@@ -4,11 +4,12 @@
 
 git -C "${execution_dir}" rev-parse HEAD > commit.info
 cp -r "${execution_dir}"/include/stdexec/* .
-cp "${execution_dir}"/include/exec/{any_sender_of,async_scope,at_coroutine_exit,env,inline_scheduler,scope,task}.hpp .
+cp "${execution_dir}"/include/exec/{any_sender_of,async_scope,at_coroutine_exit,env,inline_scheduler,scope,task,sequence_senders}.hpp .
 
 (find . -name "*.hpp" -print0 || true) | while IFS= read -r -d '' f
 do
     sed -i "s#include <stdexec/#include <sdbusplus/async/stdexec/#" -- "${f}"
     sed -i "s#include <exec/#include <sdbusplus/async/stdexec/#" -- "${f}"
+    sed -i 's#include "\./\([^"]*\)"#include <sdbusplus/async/stdexec/\1>#' -- "${f}"
     clang-format -i "${f}"
 done
diff --git a/include/sdbusplus/async/stdexec/inline_scheduler.hpp b/include/sdbusplus/async/stdexec/inline_scheduler.hpp
index 8adda7f..f100590 100644
--- a/include/sdbusplus/async/stdexec/inline_scheduler.hpp
+++ b/include/sdbusplus/async/stdexec/inline_scheduler.hpp
@@ -24,66 +24,5 @@
 {
 // A simple scheduler that executes its continuation inline, on the
 // thread of the caller of start().
-struct inline_scheduler
-{
-    template <class R_>
-    struct __op
-    {
-        using R = stdexec::__t<R_>;
-        STDEXEC_NO_UNIQUE_ADDRESS R rec_;
-
-        friend void tag_invoke(stdexec::start_t, __op& op) noexcept
-        {
-            stdexec::set_value((R&&)op.rec_);
-        }
-    };
-
-    struct __sender
-    {
-        using is_sender = void;
-        using completion_signatures =
-            stdexec::completion_signatures<stdexec::set_value_t()>;
-
-        template <class R>
-        friend auto tag_invoke(stdexec::connect_t, __sender, R&& rec) //
-            noexcept(
-                stdexec::__nothrow_constructible_from<stdexec::__decay_t<R>, R>)
-                -> __op<stdexec::__x<stdexec::__decay_t<R>>>
-        {
-            return {(R&&)rec};
-        }
-
-        struct __env
-        {
-            friend inline_scheduler tag_invoke(
-                stdexec::get_completion_scheduler_t<stdexec::set_value_t>,
-                const __env&) //
-                noexcept
-            {
-                return {};
-            }
-        };
-
-        friend __env tag_invoke(stdexec::get_env_t, const __sender&) noexcept
-        {
-            return {};
-        }
-    };
-
-    STDEXEC_DETAIL_CUDACC_HOST_DEVICE //
-        friend __sender
-        tag_invoke(stdexec::schedule_t, const inline_scheduler&) noexcept
-    {
-        return {};
-    }
-
-    friend stdexec::forward_progress_guarantee
-        tag_invoke(stdexec::get_forward_progress_guarantee_t,
-                   const inline_scheduler&) noexcept
-    {
-        return stdexec::forward_progress_guarantee::weakly_parallel;
-    }
-
-    bool operator==(const inline_scheduler&) const noexcept = default;
-};
+using inline_scheduler = stdexec::__inln::__scheduler;
 } // namespace exec
diff --git a/include/sdbusplus/async/stdexec/sequence_senders.hpp b/include/sdbusplus/async/stdexec/sequence_senders.hpp
new file mode 100644
index 0000000..88412e6
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/sequence_senders.hpp
@@ -0,0 +1,543 @@
+/*
+ * Copyright (c) 2023 Maikel Nadolski
+ * Copyright (c) 2023 NVIDIA Corporation
+ *
+ * Licensed under the Apache License Version 2.0 with LLVM Exceptions
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *   https://llvm.org/LICENSE.txt
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "../stdexec/execution.hpp"
+
+namespace exec
+{
+struct sequence_tag
+{};
+
+namespace __sequence_sndr
+{
+using namespace stdexec;
+
+template <class _Haystack>
+struct __mall_contained_in_impl
+{
+    template <class... _Needles>
+    using __f = __mand<__mapply<__contains<_Needles>, _Haystack>...>;
+};
+
+template <class _Needles, class _Haystack>
+using __mall_contained_in =
+    __mapply<__mall_contained_in_impl<_Haystack>, _Needles>;
+
+template <class _Needles, class _Haystack>
+concept __all_contained_in = __mall_contained_in<_Needles, _Haystack>::value;
+
+// This concept checks if a given sender satisfies the requirements to be
+// returned from `set_next`.
+template <class _Sender, class _Env = empty_env>
+concept next_sender =        //
+    sender_in<_Sender, _Env> //
+    &&
+    __all_contained_in<completion_signatures_of_t<_Sender, _Env>,
+                       completion_signatures<set_value_t(), set_stopped_t()>>;
+
+// This is a sequence-receiver CPO that is used to apply algorithms on an input
+// sender and it returns a next-sender. `set_next` is usually called in a
+// context where a sender will be connected to a receiver. Since calling
+// `set_next` usually involves constructing senders it is allowed to throw an
+// excpetion, which needs to be handled by a calling sequence-operation. The
+// returned object is a sender that can complete with `set_value_t()` or
+// `set_stopped_t()`.
+struct set_next_t
+{
+    template <receiver _Receiver, sender _Item>
+        requires tag_invocable<set_next_t, _Receiver&, _Item>
+    auto operator()(_Receiver& __rcvr, _Item&& __item) const
+        noexcept(nothrow_tag_invocable<set_next_t, _Receiver&, _Item>)
+            -> tag_invoke_result_t<set_next_t, _Receiver&, _Item>
+    {
+        static_assert(
+            next_sender<tag_invoke_result_t<set_next_t, _Receiver&, _Item>>,
+            "The sender returned from set_next is required to complete with set_value_t() or "
+            "set_stopped_t()");
+        return tag_invoke(*this, __rcvr, (_Item&&)__item);
+    }
+};
+} // namespace __sequence_sndr
+
+using __sequence_sndr::set_next_t;
+inline constexpr set_next_t set_next;
+
+template <class _Receiver, class _Sender>
+using next_sender_of_t = decltype(exec::set_next(
+    stdexec::__declval<stdexec::__decay_t<_Receiver>&>(),
+    stdexec::__declval<_Sender>()));
+
+namespace __sequence_sndr
+{
+
+template <class _ReceiverId>
+struct __stopped_means_break
+{
+    struct __t
+    {
+        using is_receiver = void;
+        using __id = __stopped_means_break;
+        using _Receiver = stdexec::__t<_ReceiverId>;
+        using _Token = stop_token_of_t<env_of_t<_Receiver>>;
+        STDEXEC_ATTRIBUTE((no_unique_address)) _Receiver __rcvr_;
+
+        template <same_as<get_env_t> _GetEnv, same_as<__t> _Self>
+        friend env_of_t<_Receiver> tag_invoke(_GetEnv,
+                                              const _Self& __self) noexcept
+        {
+            return stdexec::get_env(__self.__rcvr_);
+        }
+
+        template <same_as<set_value_t> _SetValue, same_as<__t> _Self>
+            requires __callable<set_value_t, _Receiver&&>
+        friend void tag_invoke(_SetValue, _Self&& __self) noexcept
+        {
+            return stdexec::set_value(static_cast<_Receiver&&>(__self.__rcvr_));
+        }
+
+        template <same_as<set_stopped_t> _SetStopped, same_as<__t> _Self>
+            requires __callable<set_value_t, _Receiver&&> &&
+                     (unstoppable_token<_Token> ||
+                      __callable<set_stopped_t, _Receiver &&>)
+        friend void tag_invoke(_SetStopped, _Self&& __self) noexcept
+        {
+            if constexpr (unstoppable_token<_Token>)
+            {
+                stdexec::set_value(static_cast<_Receiver&&>(__self.__rcvr_));
+            }
+            else
+            {
+                auto __token =
+                    stdexec::get_stop_token(stdexec::get_env(__self.__rcvr_));
+                if (__token.stop_requested())
+                {
+                    stdexec::set_stopped(
+                        static_cast<_Receiver&&>(__self.__rcvr_));
+                }
+                else
+                {
+                    stdexec::set_value(
+                        static_cast<_Receiver&&>(__self.__rcvr_));
+                }
+            }
+        }
+    };
+};
+
+template <class _Rcvr>
+using __stopped_means_break_t =
+    __t<__stopped_means_break<__id<__decay_t<_Rcvr>>>>;
+} // namespace __sequence_sndr
+
+template <class _Sender>
+concept __enable_sequence_sender =               //
+    requires { typename _Sender::is_sender; } && //
+    stdexec::same_as<typename _Sender::is_sender, sequence_tag>;
+
+template <class _Sender>
+inline constexpr bool enable_sequence_sender =
+    __enable_sequence_sender<_Sender>;
+
+template <class... _Senders>
+struct item_types
+{};
+
+template <class _Tp>
+concept __has_item_typedef = requires { typename _Tp::item_types; };
+
+/////////////////////////////////////////////////////////////////////////////
+// [execution.sndtraits]
+namespace __sequence_sndr
+{
+struct get_item_types_t;
+template <class _Sender, class _Env>
+using __tfx_sender =
+    transform_sender_result_t<__late_domain_of_t<_Sender, _Env>, _Sender, _Env>;
+
+template <class _Sender, class _Env>
+concept __with_tag_invoke = //
+    tag_invocable<get_item_types_t, __tfx_sender<_Sender, _Env>, _Env>;
+template <class _Sender, class _Env>
+using __member_alias_t = //
+    typename __decay_t<__tfx_sender<_Sender, _Env>>::item_types;
+
+template <class _Sender, class _Env>
+concept __with_member_alias = __mvalid<__member_alias_t, _Sender, _Env>;
+
+struct get_item_types_t
+{
+    template <class _Sender, class _Env>
+    static auto __impl()
+    {
+        static_assert(sizeof(_Sender),
+                      "Incomplete type used with get_item_types");
+        static_assert(sizeof(_Env), "Incomplete type used with get_item_types");
+        using _TfxSender = __tfx_sender<_Sender, _Env>;
+        if constexpr (__with_tag_invoke<_Sender, _Env>)
+        {
+            using _Result =
+                tag_invoke_result_t<get_item_types_t, _TfxSender, _Env>;
+            return (_Result(*)()) nullptr;
+        }
+        else if constexpr (__with_member_alias<_TfxSender, _Env>)
+        {
+            using _Result = __member_alias_t<_TfxSender, _Env>;
+            return (_Result(*)()) nullptr;
+        }
+        else if constexpr (sender_in<_TfxSender, _Env> &&
+                           !enable_sequence_sender<
+                               stdexec::__decay_t<_TfxSender>>)
+        {
+            using _Result = item_types<stdexec::__decay_t<_TfxSender>>;
+            return (_Result(*)()) nullptr;
+        }
+        else if constexpr (__is_debug_env<_Env>)
+        {
+            using __tag_invoke::tag_invoke;
+            // This ought to cause a hard error that indicates where the problem
+            // is.
+            using _Completions [[maybe_unused]] =
+                tag_invoke_result_t<get_item_types_t,
+                                    __tfx_sender<_Sender, _Env>, _Env>;
+            return (__debug::__completion_signatures(*)()) nullptr;
+        }
+        else
+        {
+            using _Result =
+                __mexception<_UNRECOGNIZED_SENDER_TYPE_<>,
+                             _WITH_SENDER_<_Sender>, _WITH_ENVIRONMENT_<_Env>>;
+            return (_Result(*)()) nullptr;
+        }
+    }
+
+    template <class _Sender, class _Env = __default_env>
+    constexpr auto operator()(_Sender&&, const _Env&) const noexcept
+        -> decltype(__impl<_Sender, _Env>()())
+    {
+        return {};
+    }
+};
+} // namespace __sequence_sndr
+
+using __sequence_sndr::get_item_types_t;
+inline constexpr get_item_types_t get_item_types{};
+
+template <class _Sender, class _Env>
+using item_types_of_t = decltype(get_item_types(stdexec::__declval<_Sender>(),
+                                                stdexec::__declval<_Env>()));
+
+template <class _Sender, class _Env>
+concept sequence_sender =                //
+    stdexec::sender_in<_Sender, _Env> && //
+    enable_sequence_sender<stdexec::__decay_t<_Sender>>;
+
+template <class _Sender, class _Env>
+concept has_sequence_item_types =
+    requires(_Sender&& __sndr, _Env&& __env) {
+        get_item_types((_Sender&&)__sndr, (_Env&&)__env);
+    };
+
+template <class _Sender, class _Env>
+concept sequence_sender_in =                  //
+    stdexec::sender_in<_Sender, _Env> &&      //
+    has_sequence_item_types<_Sender, _Env> && //
+    sequence_sender<_Sender, _Env>;
+
+template <class _Receiver>
+struct _WITH_RECEIVER_
+{};
+
+template <class _Item>
+struct _MISSING_SET_NEXT_OVERLOAD_FOR_ITEM_
+{};
+
+template <class _Receiver, class _Item>
+auto __try_item(_Item*)
+    -> stdexec::__mexception<_MISSING_SET_NEXT_OVERLOAD_FOR_ITEM_<_Item>,
+                             _WITH_RECEIVER_<_Receiver>>;
+
+template <class _Receiver, class _Item>
+    requires stdexec::__callable<set_next_t, _Receiver&, _Item>
+stdexec::__msuccess __try_item(_Item*);
+
+template <class _Receiver, class... _Items>
+auto __try_items(exec::item_types<_Items...>*)
+    -> decltype((stdexec::__msuccess(), ...,
+                 exec::__try_item<_Receiver>((_Items*)nullptr)));
+
+template <class _Receiver, class _Items>
+concept __sequence_receiver_of =
+    requires(_Items* __items) {
+        {
+            exec::__try_items<stdexec::__decay_t<_Receiver>>(__items)
+        } -> stdexec::__ok;
+    };
+
+template <class _Receiver, class _SequenceItems>
+concept sequence_receiver_of =      //
+    stdexec::receiver<_Receiver> && //
+    __sequence_receiver_of<_Receiver, _SequenceItems>;
+
+template <class _Items, class _Env>
+using __concat_item_signatures_t = stdexec::__mapply<
+    stdexec::__q<stdexec::__concat_completion_signatures_t>,
+    stdexec::__mapply<stdexec::__transform<stdexec::__mbind_back_q<
+                          stdexec::completion_signatures_of_t, _Env>>,
+                      _Items>>;
+
+template <class _Completions>
+using __gather_error_signals =
+    stdexec::__only_gather_signal<stdexec::set_error_t, _Completions>;
+
+template <class _Completions>
+using __gather_stopped_signals =
+    stdexec::__only_gather_signal<stdexec::set_stopped_t, _Completions>;
+
+template <class _Completions>
+using __to_sequence_completions_t = stdexec::__concat_completion_signatures_t<
+    stdexec::completion_signatures<stdexec::set_value_t()>,
+    __gather_error_signals<_Completions>,
+    __gather_stopped_signals<_Completions>>;
+
+template <class _Sender, class _Env>
+using __to_sequence_completion_signatures = stdexec::make_completion_signatures<
+    _Sender, _Env, stdexec::completion_signatures<stdexec::set_value_t()>,
+    stdexec::__mconst<stdexec::completion_signatures<>>::__f>;
+
+template <class _Sequence, class _Env>
+using __sequence_completion_signatures_of_t =
+    stdexec::__concat_completion_signatures_t<
+        stdexec::__try_make_completion_signatures<
+            _Sequence, _Env,
+            stdexec::completion_signatures<stdexec::set_value_t()>,
+            stdexec::__mconst<stdexec::completion_signatures<>>>,
+        stdexec::__mapply<
+            stdexec::__q<stdexec::__concat_completion_signatures_t>,
+            stdexec::__mapply<stdexec::__transform<stdexec::__mbind_back_q<
+                                  __to_sequence_completion_signatures, _Env>>,
+                              item_types_of_t<_Sequence, _Env>>>>;
+
+template <class _Receiver, class _Sender>
+concept sequence_receiver_from =                                              //
+    stdexec::receiver<_Receiver> &&                                           //
+    stdexec::sender_in<_Sender, stdexec::env_of_t<_Receiver>> &&              //
+    sequence_receiver_of<
+        _Receiver, item_types_of_t<_Sender, stdexec::env_of_t<_Receiver>>> && //
+    ((sequence_sender_in<_Sender, stdexec::env_of_t<_Receiver>> &&
+      stdexec::receiver_of<_Receiver,
+                           stdexec::completion_signatures_of_t<
+                               _Sender, stdexec::env_of_t<_Receiver>>>) || //
+     (!sequence_sender_in<_Sender, stdexec::env_of_t<_Receiver>> &&
+      stdexec::__receiver_from<
+          __sequence_sndr::__stopped_means_break_t<_Receiver>,
+          next_sender_of_t<_Receiver, _Sender>>));
+
+namespace __sequence_sndr
+{
+struct subscribe_t;
+
+template <class _Env>
+using __single_sender_completion_sigs =
+    __if_c<unstoppable_token<stop_token_of_t<_Env>>,
+           completion_signatures<set_value_t()>,
+           completion_signatures<set_value_t(), set_stopped_t()>>;
+
+template <class _Sender, class _Receiver>
+concept __next_connectable_with_tag_invoke =
+    receiver<_Receiver> &&                                           //
+    sender_in<_Sender, env_of_t<_Receiver>> &&                       //
+    !sequence_sender_in<_Sender, env_of_t<_Receiver>> &&             //
+    sequence_receiver_of<_Receiver,
+                         item_types<stdexec::__decay_t<_Sender>>> && //
+    __receiver_from<__stopped_means_break_t<_Receiver>,
+                    next_sender_of_t<_Receiver, _Sender>> &&         //
+    __connect::__connectable_with_tag_invoke<
+        next_sender_of_t<_Receiver, _Sender>&&,
+        __stopped_means_break_t<_Receiver>>;
+
+template <class _Sender, class _Receiver>
+concept __subscribeable_with_tag_invoke =
+    receiver<_Receiver> &&                              //
+    sequence_sender_in<_Sender, env_of_t<_Receiver>> && //
+    sequence_receiver_from<_Receiver, _Sender> &&       //
+    tag_invocable<subscribe_t, _Sender, _Receiver>;
+
+struct subscribe_t
+{
+    template <class _Sender, class _Receiver>
+    using __tfx_sndr = __tfx_sender<_Sender, env_of_t<_Receiver>>;
+
+    template <class _Sender, class _Receiver>
+    static constexpr auto __select_impl() noexcept
+    {
+        using _Domain = __late_domain_of_t<_Sender, env_of_t<_Receiver&>>;
+        constexpr bool _NothrowTfxSender =
+            __nothrow_callable<get_env_t, _Receiver&> &&
+            __nothrow_callable<transform_sender_t, _Domain, _Sender,
+                               env_of_t<_Receiver&>>;
+        using _TfxSender = __tfx_sndr<_Sender, _Receiver>;
+        if constexpr (__next_connectable_with_tag_invoke<_TfxSender, _Receiver>)
+        {
+            using _Result =
+                tag_invoke_result_t<connect_t,
+                                    next_sender_of_t<_Receiver, _TfxSender>,
+                                    __stopped_means_break_t<_Receiver>>;
+            constexpr bool _Nothrow =
+                nothrow_tag_invocable<connect_t,
+                                      next_sender_of_t<_Receiver, _TfxSender>,
+                                      __stopped_means_break_t<_Receiver>>;
+            return static_cast<_Result (*)() noexcept(_Nothrow)>(nullptr);
+        }
+        else if constexpr (__subscribeable_with_tag_invoke<_TfxSender,
+                                                           _Receiver>)
+        {
+            using _Result =
+                tag_invoke_result_t<subscribe_t, _TfxSender, _Receiver>;
+            constexpr bool _Nothrow = //
+                _NothrowTfxSender &&
+                nothrow_tag_invocable<subscribe_t, _TfxSender, _Receiver>;
+            return static_cast<_Result (*)() noexcept(_Nothrow)>(nullptr);
+        }
+        else
+        {
+            return static_cast<__debug::__debug_operation (*)() noexcept>(
+                nullptr);
+        }
+    }
+
+    template <class _Sender, class _Receiver>
+    using __select_impl_t = decltype(__select_impl<_Sender, _Receiver>());
+
+    template <sender _Sender, receiver _Receiver>
+        requires __next_connectable_with_tag_invoke<
+                     __tfx_sndr<_Sender, _Receiver>, _Receiver> ||
+                 __subscribeable_with_tag_invoke<__tfx_sndr<_Sender, _Receiver>,
+                                                 _Receiver> ||
+                 __is_debug_env<env_of_t<_Receiver>>
+    auto operator()(_Sender&& __sndr, _Receiver&& __rcvr) const
+        noexcept(__nothrow_callable<__select_impl_t<_Sender, _Receiver>>)
+            -> __call_result_t<__select_impl_t<_Sender, _Receiver>>
+    {
+        using _TfxSender = __tfx_sndr<_Sender, _Receiver>;
+        auto&& __env = get_env(__rcvr);
+        auto __domain = __get_late_domain(__sndr, __env);
+        if constexpr (__next_connectable_with_tag_invoke<_TfxSender, _Receiver>)
+        {
+            static_assert(
+                operation_state<tag_invoke_result_t<
+                    connect_t, next_sender_of_t<_Receiver, _TfxSender>,
+                    __stopped_means_break_t<_Receiver>>>,
+                "stdexec::connect(sender, receiver) must return a type that "
+                "satisfies the operation_state concept");
+            next_sender_of_t<_Receiver, _TfxSender> __next = set_next(
+                __rcvr, transform_sender(__domain, (_Sender&&)__sndr, __env));
+            return tag_invoke(
+                connect_t{},
+                static_cast<next_sender_of_t<_Receiver, _TfxSender>&&>(__next),
+                __stopped_means_break_t<_Receiver>{(_Receiver&&)__rcvr});
+        }
+        else if constexpr (__subscribeable_with_tag_invoke<_TfxSender,
+                                                           _Receiver>)
+        {
+            static_assert(
+                operation_state<
+                    tag_invoke_result_t<subscribe_t, _TfxSender, _Receiver>>,
+                "exec::subscribe(sender, receiver) must return a type that "
+                "satisfies the operation_state concept");
+            return tag_invoke(
+                subscribe_t{},
+                transform_sender(__domain, (_Sender&&)__sndr, __env),
+                (_Receiver&&)__rcvr);
+        }
+        else if constexpr (enable_sequence_sender<
+                               stdexec::__decay_t<_TfxSender>>)
+        {
+            // This should generate an instantiate backtrace that contains
+            // useful debugging information.
+            using __tag_invoke::tag_invoke;
+            tag_invoke(*this,
+                       transform_sender(__domain, (_Sender&&)__sndr, __env),
+                       (_Receiver&&)__rcvr);
+        }
+        else
+        {
+            next_sender_of_t<_Receiver, _TfxSender> __next = set_next(
+                __rcvr, transform_sender(__domain, (_Sender&&)__sndr, __env));
+            return tag_invoke(
+                connect_t{},
+                static_cast<next_sender_of_t<_Receiver, _TfxSender>&&>(__next),
+                __stopped_means_break_t<_Receiver>{(_Receiver&&)__rcvr});
+        }
+    }
+
+    friend constexpr bool tag_invoke(forwarding_query_t, subscribe_t) noexcept
+    {
+        return false;
+    }
+};
+
+template <class _Sender, class _Receiver>
+using subscribe_result_t = __call_result_t<subscribe_t, _Sender, _Receiver>;
+} // namespace __sequence_sndr
+
+using __sequence_sndr::__single_sender_completion_sigs;
+
+using __sequence_sndr::subscribe_t;
+inline constexpr subscribe_t subscribe;
+
+using __sequence_sndr::subscribe_result_t;
+
+template <class _Sender, class _Receiver>
+concept sequence_sender_to =
+    sequence_receiver_from<_Receiver, _Sender> && //
+    requires(_Sender&& __sndr, _Receiver&& __rcvr) {
+        {
+            subscribe((_Sender&&)__sndr, (_Receiver&&)__rcvr)
+        };
+    };
+
+template <class _Receiver>
+concept __stoppable_receiver =                              //
+    stdexec::__callable<stdexec::set_value_t, _Receiver> && //
+    (stdexec::unstoppable_token<
+         stdexec::stop_token_of_t<stdexec::env_of_t<_Receiver>>> ||
+     stdexec::__callable<stdexec::set_stopped_t, _Receiver>);
+
+template <class _Receiver>
+    requires __stoppable_receiver<_Receiver>
+void __set_value_unless_stopped(_Receiver&& __rcvr)
+{
+    using token_type = stdexec::stop_token_of_t<stdexec::env_of_t<_Receiver>>;
+    if constexpr (stdexec::unstoppable_token<token_type>)
+    {
+        stdexec::set_value(static_cast<_Receiver&&>(__rcvr));
+    }
+    else
+    {
+        auto token = stdexec::get_stop_token(stdexec::get_env(__rcvr));
+        if (!token.stop_requested())
+        {
+            stdexec::set_value(static_cast<_Receiver&&>(__rcvr));
+        }
+        else
+        {
+            stdexec::set_stopped(static_cast<_Receiver&&>(__rcvr));
+        }
+    }
+}
+} // namespace exec
diff --git a/include/sdbusplus/async/stdexec/stop_token.hpp b/include/sdbusplus/async/stdexec/stop_token.hpp
index 28ca42a..e23ee1f 100644
--- a/include/sdbusplus/async/stdexec/stop_token.hpp
+++ b/include/sdbusplus/async/stdexec/stop_token.hpp
@@ -261,7 +261,7 @@
         std::move(static_cast<in_place_stop_callback*>(cb)->__fun_)();
     }
 
-    STDEXEC_NO_UNIQUE_ADDRESS _Fun __fun_;
+    STDEXEC_ATTRIBUTE((no_unique_address)) _Fun __fun_;
 };
 
 namespace __stok
diff --git a/include/sdbusplus/async/stdexec/task.hpp b/include/sdbusplus/async/stdexec/task.hpp
index c2da093..379941e 100644
--- a/include/sdbusplus/async/stdexec/task.hpp
+++ b/include/sdbusplus/async/stdexec/task.hpp
@@ -30,7 +30,8 @@
 #include <variant>
 
 STDEXEC_PRAGMA_PUSH()
-STDEXEC_PRAGMA_IGNORE("-Wundefined-inline")
+STDEXEC_PRAGMA_IGNORE_GNU("-Wpragmas")
+STDEXEC_PRAGMA_IGNORE_GNU("-Wundefined-inline")
 
 namespace exec
 {
@@ -107,7 +108,7 @@
     static constexpr bool __with_scheduler = _SchedulerAffinity ==
                                              __scheduler_affinity::__sticky;
 
-    STDEXEC_NO_UNIQUE_ADDRESS
+    STDEXEC_ATTRIBUTE((no_unique_address))
     __if_c<__with_scheduler, __any_scheduler, __ignore> //
         __scheduler_{exec::inline_scheduler{}};
     in_place_stop_token __stop_token_;
@@ -389,9 +390,9 @@
   private:
     struct __final_awaitable
     {
-        static std::false_type await_ready() noexcept
+        static constexpr bool await_ready() noexcept
         {
-            return {};
+            return false;
         }
 
         static __coro::coroutine_handle<>
@@ -499,9 +500,9 @@
                 __coro_.destroy();
         }
 
-        static std::false_type await_ready() noexcept
+        static constexpr bool await_ready() noexcept
         {
-            return {};
+            return false;
         }
 
         template <class _ParentPromise2>
@@ -550,7 +551,7 @@
 
     // Make this task generally awaitable:
     friend __task_awaitable<> operator co_await(basic_task && __self) noexcept
-        requires __valid<awaiter_context_t, __promise>
+        requires __mvalid<awaiter_context_t, __promise>
     {
         return __task_awaitable<>{std::exchange(__self.__coro_, {})};
     }
@@ -569,7 +570,10 @@
                               set_error_t(std::exception_ptr), set_stopped_t()>;
 
     friend auto tag_invoke(get_completion_signatures_t, const basic_task&, auto)
-        -> __task_traits_t;
+        -> __task_traits_t
+    {
+        return {};
+    }
 
     explicit basic_task(__coro::coroutine_handle<promise_type> __coro) noexcept
         :