stdexec: update to latest commit

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: I93e33afb0ca87f425074e86f87e6cde320f20dbc
diff --git a/include/sdbusplus/async/context.hpp b/include/sdbusplus/async/context.hpp
index e60dccf..9ba424d 100644
--- a/include/sdbusplus/async/context.hpp
+++ b/include/sdbusplus/async/context.hpp
@@ -61,8 +61,8 @@
     {
         check_stop_requested();
 
-        pending_tasks.spawn(
-            std::move(execution::on(loop.get_scheduler(), std::move(sender))));
+        pending_tasks.spawn(std::move(
+            execution::starts_on(loop.get_scheduler(), std::move(sender))));
 
         spawn_watcher();
     }
diff --git a/include/sdbusplus/async/stdexec/__detail/__basic_sender.hpp b/include/sdbusplus/async/stdexec/__detail/__basic_sender.hpp
index 2505f85..0cdbdd3 100644
--- a/include/sdbusplus/async/stdexec/__detail/__basic_sender.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__basic_sender.hpp
@@ -19,6 +19,7 @@
 #include "__diagnostics.hpp"
 #include "__env.hpp"
 #include "__execution_fwd.hpp"
+#include "__manual_lifetime.hpp"
 #include "__meta.hpp"
 #include "__sender_introspection.hpp"
 #include "__senders_core.hpp"
@@ -61,7 +62,7 @@
 }
 } // namespace
 
-#if STDEXEC_NVHPC()
+#if STDEXEC_EDG()
 #define STDEXEC_SEXPR_DESCRIPTOR(_Tag, _Data, _Child)                          \
     stdexec::__descriptor_fn<_Tag, _Data, _Child>()
 #else
@@ -227,33 +228,120 @@
 //   __get_desc>::__children>;
 
 template <class _Sexpr, class _Receiver>
+using __state_t = //
+    __state_type_t<typename __decay_t<_Sexpr>::__tag_t, _Sexpr, _Receiver>;
+
+template <class _Sexpr, class _Receiver>
+struct __op_base;
+
+template <class _Receiver>
+struct __receiver_box
+{
+    _Receiver __rcvr_;
+
+    STDEXEC_ATTRIBUTE((always_inline))
+    auto __rcvr() & noexcept -> _Receiver&
+    {
+        return this->__rcvr_;
+    }
+
+    STDEXEC_ATTRIBUTE((always_inline))
+    auto __rcvr() const& noexcept -> const _Receiver&
+    {
+        return this->__rcvr_;
+    }
+};
+
+template <class _Sexpr, class _Receiver>
+struct __state_box
+{
+    using __tag_t = typename __decay_t<_Sexpr>::__tag_t;
+    using __state_t = __state_type_t<__tag_t, _Sexpr, _Receiver>;
+
+    __state_box(_Sexpr&& __sndr, _Receiver& __rcvr) //
+        noexcept(__nothrow_callable<decltype(__sexpr_impl<__tag_t>::get_state),
+                                    _Sexpr, _Receiver>) :
+        __state_(__sexpr_impl<__tag_t>::get_state(static_cast<_Sexpr&&>(__sndr),
+                                                  __rcvr))
+    {}
+
+    __state_t __state_;
+};
+
+template <class _Sexpr, class _Receiver, class _State>
+struct __enable_receiver_from_this
+{
+#if STDEXEC_HAS_FEATURE(undefined_behavior_sanitizer) && STDEXEC_CLANG()
+    // See https://github.com/llvm/llvm-project/issues/101276
+    [[clang::noinline]]
+#endif
+    auto __receiver() noexcept -> decltype(auto)
+    {
+        void* __state = static_cast<_State*>(this);
+        auto* __sbox = static_cast<__state_box<_Sexpr, _Receiver>*>(__state);
+        return (static_cast<__op_base<_Sexpr, _Receiver>*>(__sbox)->__rcvr_);
+    }
+};
+
+template <class _Sexpr, class _Receiver>
+concept __state_uses_receiver = //
+    derived_from<__state_t<_Sexpr, _Receiver>,
+                 __enable_receiver_from_this<_Sexpr, _Receiver,
+                                             __state_t<_Sexpr, _Receiver>>>;
+
+template <class _Sexpr, class _Receiver>
 struct __op_base : __immovable
 {
     using __tag_t = typename __decay_t<_Sexpr>::__tag_t;
     using __state_t = __state_type_t<__tag_t, _Sexpr, _Receiver>;
 
-    STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS _Receiver __rcvr_;
-    STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS __state_t __state_;
+    STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS
+    _Receiver __rcvr_;
+    STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS
+    __state_t __state_;
 
     __op_base(_Sexpr&& __sndr, _Receiver&& __rcvr) //
         noexcept(__nothrow_decay_copyable<_Receiver> &&
-                 __nothrow_move_constructible<__state_t>) :
+                 __nothrow_callable<decltype(__sexpr_impl<__tag_t>::get_state),
+                                    _Sexpr, _Receiver>) :
         __rcvr_(static_cast<_Receiver&&>(__rcvr)),
         __state_(__sexpr_impl<__tag_t>::get_state(static_cast<_Sexpr&&>(__sndr),
                                                   __rcvr_))
     {}
 
+    STDEXEC_ATTRIBUTE((always_inline))
     auto __rcvr() & noexcept -> _Receiver&
     {
         return __rcvr_;
     }
 
+    STDEXEC_ATTRIBUTE((always_inline))
     auto __rcvr() const& noexcept -> const _Receiver&
     {
         return __rcvr_;
     }
 };
 
+template <class _Sexpr, class _Receiver>
+    requires __state_uses_receiver<_Sexpr, _Receiver>
+struct __op_base<_Sexpr, _Receiver> :
+    __receiver_box<_Receiver>,
+    __state_box<_Sexpr, _Receiver>
+{
+    using __tag_t = typename __decay_t<_Sexpr>::__tag_t;
+    using __state_t = __state_type_t<__tag_t, _Sexpr, _Receiver>;
+
+    STDEXEC_IMMOVABLE(__op_base);
+
+    __op_base(_Sexpr&& __sndr, _Receiver&& __rcvr) //
+        noexcept(__nothrow_decay_copyable<_Receiver> &&
+                 __nothrow_move_constructible<__state_t>) :
+        __receiver_box<_Receiver>{static_cast<_Receiver&&>(__rcvr)},
+        __state_box<_Sexpr, _Receiver>{static_cast<_Sexpr&&>(__sndr),
+                                       this->__rcvr_}
+    {}
+};
+
 // template <class _Sexpr, class _Receiver>
 //   requires __is_instance_of<__id<_Receiver>, __receiver>
 //         && __decays_to<_Sexpr, __sexpr_connected_with<_Receiver>>
@@ -277,28 +365,6 @@
 // };
 
 STDEXEC_PRAGMA_PUSH()
-STDEXEC_PRAGMA_IGNORE_GNU("-Winvalid-offsetof")
-STDEXEC_PRAGMA_IGNORE_EDG(offset_in_non_POD_nonstandard)
-
-template <class _Sexpr, class _Receiver>
-struct __enable_receiver_from_this
-{
-    using __op_base_t = __op_base<_Sexpr, _Receiver>;
-
-    auto __receiver() noexcept -> decltype(auto)
-    {
-        using __derived_t = decltype(__op_base_t::__state_);
-        auto* __derived = static_cast<__derived_t*>(this);
-        constexpr std::size_t __offset = offsetof(__op_base_t, __state_);
-        auto* __base = reinterpret_cast<__op_base_t*>(
-            reinterpret_cast<char*>(__derived) - __offset);
-        return __base->__rcvr();
-    }
-};
-
-STDEXEC_PRAGMA_POP()
-
-STDEXEC_PRAGMA_PUSH()
 STDEXEC_PRAGMA_IGNORE_GNU("-Wmissing-braces")
 
 template <class _Sexpr, class _Receiver>
@@ -429,9 +495,9 @@
 constexpr auto __captures(_Tag, _Captures&&... __captures2)
 {
     return
-        [... __captures3 = static_cast<_Captures&&>(
-             __captures2)]<class _Cvref, class _Fun>(_Cvref,
-                                                     _Fun&& __fun) mutable   //
+        [... __captures3 =
+             static_cast<_Captures&&>(__captures2)]<class _Cvref, class _Fun>(
+            _Cvref, _Fun&& __fun) mutable                                    //
         noexcept(
             __nothrow_callable<_Fun, _Tag, __minvoke<_Cvref, _Captures>...>) //
         -> __call_result_t<_Fun, _Tag, __minvoke<_Cvref, _Captures>...>
@@ -481,20 +547,27 @@
 using __get_attrs_fn = __result_of<__detail::__drop_front,
                                    __mtypeof<__sexpr_impl<_Tag>::get_attrs>>;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////
-// __basic_sender
+//! A dummy type used only for diagnostic purposes.
+//! See `__sexpr` for the implementation of P2300's _`basic-sender`_.
 template <class...>
 struct __basic_sender
 {
+    // See MAINTAINERS.md#class-template-parameters for `__id` and `__t`.
     using __id = __basic_sender;
     using __t = __basic_sender;
 };
 
+//! A struct template to aid in creating senders.
+//! This struct closely resembles P2300's
+//! [_`basic-sender`_](https://eel.is/c++draft/exec#snd.expos-24), but is not an
+//! exact implementation. Note: The struct named `__basic_sender` is just a
+//! dummy type and is also not _`basic-sender`_.
 template <auto _DescriptorFn, class = __anon>
 struct __sexpr
 {
     using sender_concept = sender_t;
 
+    // See MAINTAINERS.md#class-template-parameters for `__id` and `__t`.
     using __id = __sexpr;
     using __t = __sexpr;
     using __desc_t = decltype(_DescriptorFn());
@@ -583,6 +656,9 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 // __make_sexpr
+//! A tagged function-object
+//! Takes data and children and
+//! returns `__sexpr_t<_Tag, _Data, _Child...>{_Tag(), data, children...}`.
 namespace __detail
 {
 template <class _Tag>
diff --git a/include/sdbusplus/async/stdexec/__detail/__bulk.hpp b/include/sdbusplus/async/stdexec/__detail/__bulk.hpp
index c81e62e..9faa020 100644
--- a/include/sdbusplus/async/stdexec/__detail/__bulk.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__bulk.hpp
@@ -128,15 +128,21 @@
         return {};
     };
 
+    //! This implements the core default behavior for `bulk`:
+    //! When setting value, it loops over the shape and invokes the function.
+    //! Note: This is not done in parallel. That is customized by the scheduler.
+    //! See, e.g., static_thread_pool::bulk_receiver::__t.
     static constexpr auto complete = //
         []<class _Tag, class _State, class _Receiver, class... _Args>(
             __ignore, _State& __state, _Receiver& __rcvr, _Tag,
             _Args&&... __args) noexcept -> void {
         if constexpr (std::same_as<_Tag, set_value_t>)
         {
+            // Intercept set_value and dispatch to the bulk operation.
             using __shape_t = decltype(__state.__shape_);
             if constexpr (noexcept(__state.__fun_(__shape_t{}, __args...)))
             {
+                // The noexcept version that doesn't need try/catch:
                 for (__shape_t __i{}; __i != __state.__shape_; ++__i)
                 {
                     __state.__fun_(__i, __args...);
diff --git a/include/sdbusplus/async/stdexec/__detail/__config.hpp b/include/sdbusplus/async/stdexec/__detail/__config.hpp
index acf6498..479bf9e 100644
--- a/include/sdbusplus/async/stdexec/__detail/__config.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__config.hpp
@@ -130,10 +130,15 @@
 // 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__)
+#if defined(__NVCOMPILER)
+#define STDEXEC_NVHPC(...) STDEXEC_HEAD_OR_TAIL(1, __VA_ARGS__)
+#endif
+#if defined(__INTELLISENSE__)
+#define STDEXEC_INTELLISENSE(...) STDEXEC_HEAD_OR_TAIL(1, __VA_ARGS__)
+#define STDEXEC_MSVC_HEADERS(...) STDEXEC_HEAD_OR_TAIL(1, __VA_ARGS__)
+#endif
 #elif defined(__clang__)
 #define STDEXEC_CLANG(...) STDEXEC_HEAD_OR_TAIL(1, __VA_ARGS__)
 #if defined(_MSC_VER)
@@ -146,6 +151,7 @@
 #define STDEXEC_GCC(...) STDEXEC_HEAD_OR_TAIL(1, __VA_ARGS__)
 #elif defined(_MSC_VER)
 #define STDEXEC_MSVC(...) STDEXEC_HEAD_OR_TAIL(1, __VA_ARGS__)
+#define STDEXEC_MSVC_HEADERS(...) STDEXEC_HEAD_OR_TAIL(1, __VA_ARGS__)
 #endif
 
 #ifndef STDEXEC_NVCC
@@ -172,6 +178,12 @@
 #ifndef STDEXEC_MSVC
 #define STDEXEC_MSVC(...) STDEXEC_HEAD_OR_NULL(0, __VA_ARGS__)
 #endif
+#ifndef STDEXEC_MSVC_HEADERS
+#define STDEXEC_MSVC_HEADERS(...) STDEXEC_HEAD_OR_NULL(0, __VA_ARGS__)
+#endif
+#ifndef STDEXEC_INTELLISENSE
+#define STDEXEC_INTELLISENSE(...) STDEXEC_HEAD_OR_NULL(0, __VA_ARGS__)
+#endif
 
 #if STDEXEC_NVHPC()
 #define STDEXEC_NVHPC_VERSION()                                                \
@@ -274,7 +286,7 @@
 #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()
+#elif STDEXEC_EDG()
 #define STDEXEC_PRAGMA_PUSH()                                                  \
     _Pragma("diagnostic push") STDEXEC_PRAGMA_IGNORE_EDG(invalid_error_number)
 #define STDEXEC_PRAGMA_POP() _Pragma("diagnostic pop")
diff --git a/include/sdbusplus/async/stdexec/__detail/__connect_awaitable.hpp b/include/sdbusplus/async/stdexec/__detail/__connect_awaitable.hpp
index b9d2623..7cddb81 100644
--- a/include/sdbusplus/async/stdexec/__detail/__connect_awaitable.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__connect_awaitable.hpp
@@ -117,7 +117,11 @@
     {
         using __id = __promise;
 
+#if STDEXEC_EDG()
+        __t(auto&&, _Receiver&& __rcvr) noexcept : __rcvr_(__rcvr) {}
+#else
         explicit __t(auto&, _Receiver& __rcvr) noexcept : __rcvr_(__rcvr) {}
+#endif
 
         auto unhandled_stopped() noexcept -> __coro::coroutine_handle<>
         {
diff --git a/include/sdbusplus/async/stdexec/__detail/__continues_on.hpp b/include/sdbusplus/async/stdexec/__detail/__continues_on.hpp
new file mode 100644
index 0000000..d8af7af
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__continues_on.hpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2021-2024 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__basic_sender.hpp"
+#include "__concepts.hpp"
+#include "__env.hpp"
+#include "__meta.hpp"
+#include "__schedule_from.hpp"
+#include "__schedulers.hpp"
+#include "__sender_adaptor_closure.hpp"
+#include "__sender_introspection.hpp"
+#include "__senders.hpp"
+#include "__tag_invoke.hpp"
+#include "__transform_sender.hpp"
+#include "__type_traits.hpp"
+
+#include <utility>
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.adaptors.continues_on]
+namespace __continues_on
+{
+using __schfr::__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>>;
+
+struct continues_on_t
+{
+    template <sender _Sender, scheduler _Scheduler>
+    auto operator()(_Sender&& __sndr,
+                    _Scheduler&& __sched) const -> __well_formed_sender auto
+    {
+        auto __domain = __get_early_domain(__sndr);
+        using _Env = __t<__environ<__id<__decay_t<_Scheduler>>>>;
+        return stdexec::transform_sender(
+            __domain, __make_sexpr<continues_on_t>(
+                          _Env{{static_cast<_Scheduler&&>(__sched)}},
+                          static_cast<_Sender&&>(__sndr)));
+    }
+
+    template <scheduler _Scheduler>
+    STDEXEC_ATTRIBUTE((always_inline))
+    auto operator()(_Scheduler&& __sched) const
+        -> __binder_back<continues_on_t, __decay_t<_Scheduler>>
+    {
+        return {{static_cast<_Scheduler&&>(__sched)}, {}, {}};
+    }
+
+    //////////////////////////////////////////////////////////////////////////////////////////////
+    using _Env = __0;
+    using _Sender = __1;
+    using __legacy_customizations_t = //
+        __types<tag_invoke_t(continues_on_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(continues_on_t, _Sender,
+                             get_completion_scheduler_t<set_value_t>(_Env))>;
+
+    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),
+                                 static_cast<_Child&&>(__child));
+        };
+    }
+
+    template <class _Sender, class _Env>
+    static auto transform_sender(_Sender&& __sndr, const _Env& __env)
+    {
+        return __sexpr_apply(static_cast<_Sender&&>(__sndr),
+                             __transform_sender_fn(__env));
+    }
+};
+
+struct __continues_on_impl : __sexpr_defaults
+{
+    static constexpr auto get_attrs = //
+        []<class _Data, class _Child>(
+            const _Data& __data,
+            const _Child& __child) noexcept -> decltype(auto) {
+        return __env::__join(__data, stdexec::get_env(__child));
+    };
+
+    static constexpr auto get_completion_signatures = //
+        []<class _Sender>(_Sender&&) noexcept         //
+        -> __completion_signatures_of_t<              //
+            transform_sender_result_t<default_domain, _Sender, empty_env>> {};
+};
+} // namespace __continues_on
+
+using __continues_on::continues_on_t;
+inline constexpr continues_on_t continues_on{};
+
+using transfer_t = continues_on_t;
+inline constexpr continues_on_t transfer{};
+
+using continue_on_t = continues_on_t;
+inline constexpr continues_on_t continue_on{};
+
+template <>
+struct __sexpr_impl<continues_on_t> : __continues_on::__continues_on_impl
+{};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__domain.hpp b/include/sdbusplus/async/stdexec/__detail/__domain.hpp
index 329483b..42ea9e1 100644
--- a/include/sdbusplus/async/stdexec/__detail/__domain.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__domain.hpp
@@ -245,6 +245,11 @@
 } // namespace __detail
 
 /////////////////////////////////////////////////////////////////////////////
+//! Function object implementing `get-domain-early(snd)`
+//! from [exec.snd.general] item 3.9. It is the first well-formed expression of
+//! a) `get_domain(get_env(sndr))`
+//! b) `completion-domain(sndr)`
+//! c) `default_domain()`
 inline constexpr struct __get_early_domain_t
 {
     template <class _Sender, class _Default = default_domain>
@@ -299,10 +304,10 @@
         }
     }
 
-    // The transfer algorithm is the exception to the rule. It ignores the
+    // The continues_on 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>
+    template <sender_expr_for<continues_on_t> _Sender, class _Env>
     auto operator()(const _Sender& __sndr, const _Env&) const noexcept
     {
         return __sexpr_apply(__sndr, [](__ignore, auto& __data,
diff --git a/include/sdbusplus/async/stdexec/__detail/__env.hpp b/include/sdbusplus/async/stdexec/__detail/__env.hpp
index 5ff161f..6f655f7 100644
--- a/include/sdbusplus/async/stdexec/__detail/__env.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__env.hpp
@@ -192,7 +192,10 @@
     auto operator()() const noexcept;
 };
 
-struct get_delegatee_scheduler_t : __query<get_delegatee_scheduler_t>
+//! The type for `get_delegation_scheduler` [exec.get.delegation.scheduler]
+//! A query object that asks for a scheduler that can be used to delegate
+//! work to for the purpose of forward progress delegation ([intro.progress]).
+struct get_delegation_scheduler_t : __query<get_delegation_scheduler_t>
 {
     static constexpr auto query(forwarding_query_t) noexcept -> bool
     {
@@ -200,11 +203,11 @@
     }
 
     template <class _Env>
-        requires tag_invocable<get_delegatee_scheduler_t, const _Env&>
+        requires tag_invocable<get_delegation_scheduler_t, const _Env&>
     auto operator()(const _Env& __t) const noexcept
-        -> tag_invoke_result_t<get_delegatee_scheduler_t, const _Env&>;
+        -> tag_invoke_result_t<get_delegation_scheduler_t, const _Env&>;
 
-    template <class _Tag = get_delegatee_scheduler_t>
+    template <class _Tag = get_delegation_scheduler_t>
     auto operator()() const noexcept;
 };
 
@@ -353,19 +356,22 @@
 } // namespace __queries
 
 using __queries::__has_algorithm_customizations_t;
-using __queries::__is_scheduler_affine_t;
-using __queries::__root_env;
-using __queries::__root_t;
 using __queries::execute_may_block_caller_t;
 using __queries::forwarding_query_t;
 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_delegation_scheduler_t;
 using __queries::get_forward_progress_guarantee_t;
 using __queries::get_scheduler_t;
-using __queries::get_stop_token_t;
 using __queries::query_or_t;
+using get_delegatee_scheduler_t [[deprecated(
+    "get_delegatee_scheduler_t has been renamed get_delegation_scheduler_t")]] =
+    get_delegation_scheduler_t;
+using __queries::__is_scheduler_affine_t;
+using __queries::__root_env;
+using __queries::__root_t;
+using __queries::get_completion_scheduler_t;
+using __queries::get_domain_t;
+using __queries::get_stop_token_t;
 
 inline constexpr forwarding_query_t forwarding_query{};
 inline constexpr query_or_t query_or{}; // NOT TO SPEC
@@ -375,7 +381,10 @@
 inline constexpr get_forward_progress_guarantee_t
     get_forward_progress_guarantee{};
 inline constexpr get_scheduler_t get_scheduler{};
-inline constexpr get_delegatee_scheduler_t get_delegatee_scheduler{};
+inline constexpr get_delegation_scheduler_t get_delegation_scheduler{};
+inline constexpr auto& get_delegatee_scheduler [[deprecated(
+    "get_delegatee_scheduler has been renamed get_delegation_scheduler")]] =
+    get_delegation_scheduler;
 inline constexpr get_allocator_t get_allocator{};
 inline constexpr get_stop_token_t get_stop_token{};
 #if !STDEXEC_GCC() || defined(__OPTIMIZE_SIZE__)
diff --git a/include/sdbusplus/async/stdexec/__detail/__execution_fwd.hpp b/include/sdbusplus/async/stdexec/__detail/__execution_fwd.hpp
index 7b25130..b5e58df 100644
--- a/include/sdbusplus/async/stdexec/__detail/__execution_fwd.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__execution_fwd.hpp
@@ -91,7 +91,7 @@
 struct get_forward_progress_guarantee_t;
 struct __has_algorithm_customizations_t;
 struct get_scheduler_t;
-struct get_delegatee_scheduler_t;
+struct get_delegation_scheduler_t;
 struct get_allocator_t;
 struct get_stop_token_t;
 template <__completion_tag _CPO>
@@ -103,7 +103,7 @@
 using __queries::forwarding_query_t;
 using __queries::get_allocator_t;
 using __queries::get_completion_scheduler_t;
-using __queries::get_delegatee_scheduler_t;
+using __queries::get_delegation_scheduler_t;
 using __queries::get_forward_progress_guarantee_t;
 using __queries::get_scheduler_t;
 using __queries::get_stop_token_t;
@@ -113,7 +113,7 @@
 extern const __has_algorithm_customizations_t __has_algorithm_customizations;
 extern const get_forward_progress_guarantee_t get_forward_progress_guarantee;
 extern const get_scheduler_t get_scheduler;
-extern const get_delegatee_scheduler_t get_delegatee_scheduler;
+extern const get_delegation_scheduler_t get_delegation_scheduler;
 extern const get_allocator_t get_allocator;
 extern const get_stop_token_t get_stop_token;
 template <__completion_tag _CPO>
@@ -207,28 +207,43 @@
 extern const as_awaitable_t as_awaitable;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
-namespace __start_on
+namespace __starts_on_ns
 {
-struct start_on_t;
-} // namespace __start_on
+struct starts_on_t;
+} // namespace __starts_on_ns
 
-using __start_on::start_on_t;
-extern const start_on_t start_on;
+using __starts_on_ns::starts_on_t;
+extern const starts_on_t starts_on;
 
-using on_t = start_on_t;
-extern const on_t on;
+using on_t [[deprecated("on_t has been renamed starts_on_t")]] = starts_on_t;
+[[deprecated("on has been renamed starts_on")]] extern const starts_on_t on;
+
+using start_on_t
+    [[deprecated("start_on_t has been renamed starts_on_t")]] = starts_on_t;
+[[deprecated(
+    "start_on has been renamed starts_on")]] extern const starts_on_t start_on;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
-namespace __continue_on
+namespace __continues_on
 {
-struct continue_on_t;
-} // namespace __continue_on
+struct continues_on_t;
+} // namespace __continues_on
 
-using __continue_on::continue_on_t;
-extern const continue_on_t continue_on;
+using __continues_on::continues_on_t;
+extern const continues_on_t continues_on;
 
-using transfer_t = continue_on_t;
-extern const transfer_t transfer;
+using transfer_t [[deprecated("transfer_t has been renamed continues_on_t")]] =
+    continues_on_t;
+[[deprecated(
+    "transfer has been renamed continues_on")]] extern const continues_on_t
+    transfer;
+
+using continue_t
+    [[deprecated("continue_on_t has been renamed continues_on_t")]] =
+        continues_on_t;
+[[deprecated(
+    "continue_on has been renamed continues_on")]] extern const continues_on_t
+    continue_on;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 namespace __transfer_just
diff --git a/include/sdbusplus/async/stdexec/__detail/__let.hpp b/include/sdbusplus/async/stdexec/__detail/__let.hpp
index 1ea3a6d..8930589 100644
--- a/include/sdbusplus/async/stdexec/__detail/__let.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__let.hpp
@@ -155,7 +155,7 @@
 struct _FUNCTION_MUST_RETURN_A_VALID_SENDER_IN_THE_CURRENT_ENVIRONMENT_
 {};
 
-#if STDEXEC_NVHPC()
+#if STDEXEC_EDG()
 template <class _Sender, class _Set, class... _Env>
 struct __bad_result_sender_
 {
@@ -380,6 +380,9 @@
     };
 }
 
+//! Metafunction creating the operation state needed to connect the result of
+//! calling the sender factory function, `_Fun`, and passing its result to a
+//! receiver.
 template <class _Receiver, class _Fun, class _Set, class _Sched>
 struct __op_state_for
 {
@@ -390,6 +393,9 @@
         _Sched, _Receiver>;
 };
 
+//! The core of the operation state for `let_*`.
+//! This gets bundled up into a larger operation state
+//! (`__detail::__op_state<...>`).
 template <class _Receiver, class _Fun, class _Set, class _Sched,
           class... _Tuples>
 struct __let_state
@@ -443,12 +449,20 @@
         }
     }
 
-    STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS _Fun __fun_;
-    STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS _Sched __sched_;
+    STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS
+    _Fun __fun_;
+    STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS
+    _Sched __sched_;
+    //! Variant to hold the results passed from upstream before passing them to
+    //! the function:
     __result_variant __args_{};
+    //! Variant type for holding the operation state from connecting
+    //! the function result to the downstream receiver:
     __op_state_variant __op_state3_{};
 };
 
+//! Implementation of the `let_*_t` types, where `_Set` is, e.g., `set_value_t`
+//! for `let_value`.
 template <class _Set, class _Domain>
 struct __let_t
 {
@@ -541,13 +555,21 @@
                 });
         };
 
+    //! Helper function to actually invoke the function to produce `let_*`'s
+    //! sender, connect it to the downstream receiver, and start it. This is the
+    //! heart of `let_*`.
     template <class _State, class _OpState, class... _As>
     static void __bind_(_State& __state, _OpState& __op_state, _As&&... __as)
     {
+        // Store the passed-in (received) args:
         auto& __args = __state.__args_.emplace_from(
             __tup::__mktuple, static_cast<_As&&>(__as)...);
+        // Apply the function to the args to get the sender:
         auto __sndr2 = __args.apply(std::move(__state.__fun_), __args);
+        // Create a receiver based on the state, the computed sender, and the
+        // operation state:
         auto __rcvr2 = __state.__get_result_receiver(__sndr2, __op_state);
+        // Connect the sender to the receiver and start it:
         auto& __op2 = __state.__op_state3_.emplace_from(
             stdexec::connect, std::move(__sndr2), std::move(__rcvr2));
         stdexec::start(__op2);
@@ -595,10 +617,13 @@
             _As&&... __as) noexcept -> void {
         if constexpr (__same_as<_Tag, _Set>)
         {
+            // Intercept the channel of interest to compute the sender and
+            // connect it:
             __bind(__op_state, static_cast<_As&&>(__as)...);
         }
         else
         {
+            // Forward the other channels downstream:
             using _Receiver = decltype(__op_state.__rcvr_);
             _Tag()(static_cast<_Receiver&&>(__op_state.__rcvr_),
                    static_cast<_As&&>(__as)...);
diff --git a/include/sdbusplus/async/stdexec/__detail/__manual_lifetime.hpp b/include/sdbusplus/async/stdexec/__detail/__manual_lifetime.hpp
new file mode 100644
index 0000000..82fb917
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__manual_lifetime.hpp
@@ -0,0 +1,107 @@
+/*
+ * 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 "../concepts.hpp"
+
+#include <cstddef>
+#include <memory>
+#include <new>
+#include <type_traits>
+
+namespace stdexec
+{
+
+//! Holds storage for a `_Ty`, but allows clients to `__construct(...)`,
+//! `__destry()`, and `__get()` the `_Ty` without regard for usual lifetime
+//! rules.
+template <class _Ty>
+class __manual_lifetime
+{
+  public:
+    //! Constructor does nothing: It's on you to call `__construct(...)` or
+    //! `__construct_from(...)` if you want the `_Ty`'s lifetime to begin.
+    constexpr __manual_lifetime() noexcept {}
+    //! Destructor does nothing: It's on you to call `__destroy()` if you mean
+    //! to.
+    constexpr ~__manual_lifetime() {}
+
+    __manual_lifetime(const __manual_lifetime&) = delete;
+    auto operator=(const __manual_lifetime&) -> __manual_lifetime& = delete;
+
+    __manual_lifetime(__manual_lifetime&&) = delete;
+    auto operator=(__manual_lifetime&&) -> __manual_lifetime& = delete;
+
+    //! Construct the `_Ty` in place.
+    //! There are no safeties guarding against the case that there's already one
+    //! there.
+    template <class... _Args>
+    auto __construct(_Args&&... __args) noexcept(
+        stdexec::__nothrow_constructible_from<_Ty, _Args...>) -> _Ty&
+    {
+        // Use placement new instead of std::construct_at to support aggregate
+        // initialization with brace elision.
+        return *std::launder(::new (static_cast<void*>(__buffer_))
+                                 _Ty{static_cast<_Args&&>(__args)...});
+    }
+
+    //! Construct the `_Ty` in place from the result of calling `func`.
+    //! There are no safeties guarding against the case that there's already one
+    //! there.
+    template <class _Func, class... _Args>
+    auto __construct_from(_Func&& func, _Args&&... __args) -> _Ty&
+    {
+        // Use placement new instead of std::construct_at in case the function
+        // returns an immovable type.
+        return *std::launder(::new (static_cast<void*>(__buffer_)) _Ty{
+            (static_cast<_Func&&>(func))(static_cast<_Args&&>(__args)...)});
+    }
+    //! End the lifetime of the contained `_Ty`.
+    //! Precondition: The lifetime has started.
+    void __destroy() noexcept
+    {
+        std::destroy_at(&__get());
+    }
+    //! Get access to the `_Ty`.
+    //! Precondition: The lifetime has started.
+    auto __get() & noexcept -> _Ty&
+    {
+        return *reinterpret_cast<_Ty*>(__buffer_);
+    }
+
+    //! Get access to the `_Ty`.
+    //! Precondition: The lifetime has started.
+    auto __get() && noexcept -> _Ty&&
+    {
+        return static_cast<_Ty&&>(*reinterpret_cast<_Ty*>(__buffer_));
+    }
+
+    //! Get access to the `_Ty`.
+    //! Precondition: The lifetime has started.
+    auto __get() const& noexcept -> const _Ty&
+    {
+        return *reinterpret_cast<const _Ty*>(__buffer_);
+    }
+
+    //! Move semantics aren't supported.
+    //! If you want to move the `_Ty`, use `std::move(ml.__get())`.
+    auto __get() const&& noexcept -> const _Ty&& = delete;
+
+  private:
+    alignas(_Ty) unsigned char __buffer_[sizeof(_Ty)]{};
+};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__meta.hpp b/include/sdbusplus/async/stdexec/__detail/__meta.hpp
index dda9a28..1e9931e 100644
--- a/include/sdbusplus/async/stdexec/__detail/__meta.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__meta.hpp
@@ -29,6 +29,9 @@
 
 namespace stdexec
 {
+//! Convenience metafunction getting the dependant type `__t` out of `_Tp`.
+//! That is, `typename _Tp::__t`.
+//! See MAINTAINERS.md#class-template-parameters for details.
 template <class _Tp>
 using __t = typename _Tp::__t;
 
@@ -86,7 +89,10 @@
 {
 };
 
-#if STDEXEC_MSVC()
+#if STDEXEC_NVCC() || STDEXEC_EDG()
+template <std::size_t _Np>
+using __msize_t = std::integral_constant<std::size_t, _Np>;
+#elif STDEXEC_MSVC()
 template <std::size_t _Np>
 using __msize_t = __mconstant<_Np>;
 #else
@@ -94,9 +100,11 @@
 using __msize_t = __muchar (*)[_Np + 1]; // +1 to avoid zero-size array
 #endif
 
+//! Metafunction selects the first of two type arguments.
 template <class _Tp, class _Up>
 using __mfirst = _Tp;
 
+//! Metafunction selects the second of two type arguments.
 template <class _Tp, class _Up>
 using __msecond = _Up;
 
@@ -212,7 +220,7 @@
 template <std::size_t _Len>
 struct __mstring
 {
-#if STDEXEC_NVHPC()
+#if STDEXEC_EDG()
     template <std::size_t _Ny, std::size_t... _Is>
     constexpr __mstring(const char (&__str)[_Ny], __indices<_Is...>) noexcept :
         __what_{(_Is < _Ny ? __str[_Is] : '\0')...}
@@ -248,7 +256,7 @@
         return false;
     }
 
-#if !STDEXEC_NVHPC()
+#if !STDEXEC_EDG()
     constexpr auto operator<=>(const __mstring&) const noexcept
         -> std::strong_ordering = default;
 #endif
@@ -353,10 +361,20 @@
 template <class... _Args>
 concept _Ok = (STDEXEC_IS_SAME(__ok_t<_Args>, __msuccess) && ...);
 
+//! The struct `__i` is the implementation of P2300's
+//! [_`META-APPLY`_](https://eel.is/c++draft/exec#util.cmplsig-5).
+//! > [Note [1](https://eel.is/c++draft/exec#util.cmplsig-note-1): 
+//! > The purpose of META-APPLY is to make it valid to use non-variadic
+//! > templates as Variant and Tuple arguments to gather-signatures. — end note]
+//! In addition to avoiding the dreaded "pack expanded into non-pack argument"
+//! error, it is part of the meta-error propagation mechanism. if any of the
+//! argument types are a specialization of `_ERROR_`, `__i` will short-circuit
+//! and return the error.
+//! `__minvoke` and `__meval` are implemented in terms of `__i`.
 template <bool _ArgsOK, bool _FnOK = true>
 struct __i;
 
-#if STDEXEC_NVHPC()
+#if STDEXEC_EDG()
 // Most compilers memoize alias template specializations, but
 // nvc++ does not. So we memoize the type computations by
 // indirecting through a class template specialization.
@@ -406,6 +424,10 @@
     typename __i<_Ok<_Args...>>    //
     ::template __g<_Fn, _Args...>; //
 
+//! Metafunction invocation
+//! Given a metafunction, `_Fn`, and args.
+//! We expect `_Fn::__f` to be type alias template "implementing" the
+//! metafunction `_Fn`.
 template <class _Fn, class... _Args>
 using __minvoke =                         //
     typename __i<_Ok<_Args...>, _Ok<_Fn>> //
@@ -450,6 +472,16 @@
     using __f = _Fn;
 };
 
+//! This struct template is like
+//! [mpl::quote](https://www.boost.org/doc/libs/1_86_0/libs/mpl/doc/refmanual/quote.html).
+//! It turns an alias/class template into a metafunction that also propagates
+//! "meta-exceptions". All of the meta utilities recognize specializations of
+//! stdexec::_ERROR_ as an error type. Error types short-circuit the evaluation
+//! of the metafunction and are automatically propagated like an exception.
+//! Note: `__minvoke` and `__meval` also participate in this error propagation.
+//!
+//! This design lets us report type errors briefly at the library boundary, even
+//! if the actual error happens deep inside a meta-program.
 template <template <class...> class _Fn>
 struct __q
 {
@@ -549,6 +581,9 @@
 
 struct __if_
 {
+    //! Metafunction selects `_True` if the bool template is `true`, otherwise
+    //! the second. That is, `__<true>::__f<A, B>` is `A` and `__<false>::__f<A,
+    //! B>` is B. This is similar to `std::conditional_t<Cond, A, B>`.
     template <bool>
     struct __
     {
@@ -560,6 +595,7 @@
     using __f = __minvoke<__<static_cast<bool>(__v<_Pred>)>, _True, _False...>;
 };
 
+// Specialization; see above.
 template <>
 struct __if_::__<false>
 {
@@ -736,6 +772,20 @@
     using __f = __minvoke<_Fn, _As...>;
 };
 
+template <std::size_t... _Ns>
+struct __muncurry_<__pack::__t<_Ns...>*>
+{
+    template <class _Fn>
+    using __f = __minvoke<_Fn, __msize_t<_Ns>...>;
+};
+
+template <template <class _Np, _Np...> class _Cp, class _Np, _Np... _Ns>
+struct __muncurry_<_Cp<_Np, _Ns...>>
+{
+    template <class _Fn>
+    using __f = __minvoke<_Fn, std::integral_constant<_Np, _Ns>...>;
+};
+
 template <class _What, class... _With>
 struct __muncurry_<_ERROR_<_What, _With...>>
 {
@@ -897,9 +947,13 @@
 template <class _Default>
 using __msingle_or = __mbind_front_q<__msingle_or_, _Default>;
 
+//! A concept checking if `_Ty` has a dependent type `_Ty::__id`.
+//! See MAINTAINERS.md#class-template-parameters.
 template <class _Ty>
 concept __has_id = requires { typename _Ty::__id; };
 
+//! Identity mapping `_Ty` to itself.
+//! That is, `std::is_same_v<T, typename _Id<T>::__t>`.
 template <class _Ty>
 struct _Id
 {
@@ -913,6 +967,7 @@
     // static_assert(!__has_id<std::remove_cvref_t<_Ty>>);
 };
 
+//! Helper metafunction detail of `__id`, below.
 template <bool = true>
 struct __id_
 {
@@ -926,6 +981,11 @@
     template <class _Ty>
     using __f = _Id<_Ty>;
 };
+
+//! Metafunction mapping `_Ty` to either
+//! * `typename _Ty::__id` if that exists, or to
+//! * `_Ty` (itself) otherwise.
+//! See MAINTAINERS.md#class-template-parameters.
 template <class _Ty>
 using __id = __minvoke<__id_<__has_id<_Ty>>, _Ty>;
 
@@ -935,7 +995,7 @@
 template <class _From, class _To = __decay_t<_From>>
 using __cvref_id = __copy_cvref_t<_From, __id<_To>>;
 
-#if STDEXEC_NVHPC()
+#if STDEXEC_EDG()
 // nvc++ doesn't cache the results of alias template specializations.
 // To avoid repeated computation of the same function return type,
 // cache the result ourselves in a class template specialization.
@@ -949,7 +1009,7 @@
 #endif
 
 // BUGBUG TODO file this bug with nvc++
-#if STDEXEC_NVHPC()
+#if STDEXEC_EDG()
 template <const auto& _Fun, class... _As>
 using __result_of = __call_result_t<decltype(_Fun), _As...>;
 #else
@@ -982,8 +1042,11 @@
 template <class _Fn>
 __emplace_from(_Fn) -> __emplace_from<_Fn>;
 
-template <class, class, class, class>
-struct __mzip_with2_;
+template <class _Fn, class _Continuation, class _List1, class _List2>
+struct __mzip_with2_ :
+    __mzip_with2_<_Fn, _Continuation, __mapply<__qq<__types>, _List1>,
+                  __mapply<__qq<__types>, _List2>>
+{};
 
 template <               //
     class _Fn,           //
@@ -1062,7 +1125,7 @@
 template <class _Boolean>
 using __mnot = __meval<__mnot_t, _Boolean>;
 
-#if STDEXEC_NVHPC()
+#if STDEXEC_EDG()
 template <class... _Ints>
 struct __mplus_t : __mconstant<(__v<_Ints> + ...)>
 {};
@@ -1094,7 +1157,9 @@
     using __f = __mor<__minvoke<_Fn, _Args>...>;
 };
 
-#if defined(__cpp_pack_indexing)
+// C++23 pack indexing is disabled for clang because of
+// https://github.com/llvm/llvm-project/issues/116105
+#if defined(__cpp_pack_indexing) && !STDEXEC_CLANG()
 template <class _Np, class... _Ts>
 using __m_at = _Ts...[__v<_Np>];
 
@@ -1188,7 +1253,7 @@
     constexpr decltype(auto) operator()(_Ts&&... __ts) const noexcept
     {
         static_assert(_Np < sizeof...(_Ts));
-        return (static_cast<_Ts&&>(__ts)...[_Np]);
+        return static_cast<_Ts...[_Np] &&>(__ts...[_Np]);
     }
 };
 #else
diff --git a/include/sdbusplus/async/stdexec/__detail/__on.hpp b/include/sdbusplus/async/stdexec/__detail/__on.hpp
index 0d5d522..5f257bf 100644
--- a/include/sdbusplus/async/stdexec/__detail/__on.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__on.hpp
@@ -20,7 +20,7 @@
 // include these after __execution_fwd.hpp
 #include "__basic_sender.hpp"
 #include "__concepts.hpp"
-#include "__continue_on.hpp"
+#include "__continues_on.hpp"
 #include "__cpo.hpp"
 #include "__diagnostics.hpp"
 #include "__domain.hpp"
@@ -71,14 +71,13 @@
 };
 
 template <class _Scheduler, class _Closure>
-struct __continue_on_data
+struct __on_data
 {
     _Scheduler __sched_;
     _Closure __clsur_;
 };
 template <class _Scheduler, class _Closure>
-__continue_on_data(_Scheduler,
-                   _Closure) -> __continue_on_data<_Scheduler, _Closure>;
+__on_data(_Scheduler, _Closure) -> __on_data<_Scheduler, _Closure>;
 
 template <class _Scheduler>
 struct __with_sched
@@ -122,10 +121,10 @@
     {
         auto __domain = __get_early_domain(__sndr);
         return stdexec::transform_sender(
-            __domain, __make_sexpr<on_t>(
-                          __continue_on_data{static_cast<_Scheduler&&>(__sched),
-                                             static_cast<_Closure&&>(__clsur)},
-                          static_cast<_Sender&&>(__sndr)));
+            __domain,
+            __make_sexpr<on_t>(__on_data{static_cast<_Scheduler&&>(__sched),
+                                         static_cast<_Closure&&>(__clsur)},
+                               static_cast<_Sender&&>(__sndr)));
     }
 
     template <scheduler _Scheduler, __sender_adaptor_closure _Closure>
@@ -172,9 +171,9 @@
                 {
                     if constexpr (__is_root_env<_Env>)
                     {
-                        return continue_on(
-                            start_on(static_cast<_Data&&>(__data),
-                                     static_cast<_Child&&>(__child)),
+                        return continues_on(
+                            starts_on(static_cast<_Data&&>(__data),
+                                      static_cast<_Child&&>(__child)),
                             __inln::__scheduler{});
                     }
                     else
@@ -184,9 +183,10 @@
                 }
                 else
                 {
-                    return continue_on(start_on(static_cast<_Data&&>(__data),
-                                                static_cast<_Child&&>(__child)),
-                                       static_cast<decltype(__old)&&>(__old));
+                    return continues_on(
+                        starts_on(static_cast<_Data&&>(__data),
+                                  static_cast<_Child&&>(__child)),
+                        static_cast<decltype(__old)&&>(__old));
                 }
             }
             else
@@ -204,9 +204,9 @@
                 {
                     auto&& [__sched, __clsur] = static_cast<_Data&&>(__data);
                     return __write_env(                               //
-                        continue_on(                                  //
+                        continues_on(                                 //
                             __forward_like<_Data>(__clsur)(           //
-                                continue_on(                          //
+                                continues_on(                         //
                                     __write_env(static_cast<_Child&&>(__child),
                                                 __with_sched{__old}), //
                                     __sched)),                        //
diff --git a/include/sdbusplus/async/stdexec/__detail/__read_env.hpp b/include/sdbusplus/async/stdexec/__detail/__read_env.hpp
index e617901..23ab05a 100644
--- a/include/sdbusplus/async/stdexec/__detail/__read_env.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__read_env.hpp
@@ -147,9 +147,9 @@
 }
 
 template <class _Tag>
-inline auto get_delegatee_scheduler_t::operator()() const noexcept
+inline auto get_delegation_scheduler_t::operator()() const noexcept
 {
-    return read_env(get_delegatee_scheduler);
+    return read_env(get_delegation_scheduler);
 }
 
 template <class _Tag>
diff --git a/include/sdbusplus/async/stdexec/__detail/__receivers.hpp b/include/sdbusplus/async/stdexec/__detail/__receivers.hpp
index 11c1708..a3e365c 100644
--- a/include/sdbusplus/async/stdexec/__detail/__receivers.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__receivers.hpp
@@ -147,8 +147,8 @@
 namespace __detail
 {
 template <class _Receiver>
-concept __enable_receiver =                                              //
-    (STDEXEC_NVHPC(requires { typename _Receiver::receiver_concept; }&&) //
+concept __enable_receiver =                                            //
+    (STDEXEC_EDG(requires { typename _Receiver::receiver_concept; }&&) //
      derived_from<typename _Receiver::receiver_concept, receiver_t>) ||
     requires { typename _Receiver::is_receiver; } // back-compat, NOT TO SPEC
     || STDEXEC_IS_BASE_OF(receiver_t,
diff --git a/include/sdbusplus/async/stdexec/__detail/__schedule_from.hpp b/include/sdbusplus/async/stdexec/__detail/__schedule_from.hpp
index 3f60705..0f83452 100644
--- a/include/sdbusplus/async/stdexec/__detail/__schedule_from.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__schedule_from.hpp
@@ -175,18 +175,19 @@
 };
 
 template <class _Scheduler, class _Sexpr, class _Receiver>
-struct __state : __enable_receiver_from_this<_Sexpr, _Receiver>, __immovable
+struct __state :
+    __enable_receiver_from_this<_Sexpr, _Receiver,
+                                __state<_Scheduler, _Sexpr, _Receiver>>,
+    __immovable
 {
     using __variant_t = __variant_for<__child_of<_Sexpr>, env_of_t<_Receiver>>;
     using __receiver2_t = __receiver2<_Scheduler, _Sexpr, _Receiver>;
 
     __variant_t __data_;
     connect_result_t<schedule_result_t<_Scheduler>, __receiver2_t> __state2_;
-    STDEXEC_APPLE_CLANG(__state* __self_;)
 
     explicit __state(_Scheduler __sched) :
         __data_(), __state2_(connect(schedule(__sched), __receiver2_t{this}))
-                       STDEXEC_APPLE_CLANG(, __self_(this))
     {}
 };
 
@@ -245,8 +246,6 @@
         []<class _State, class _Receiver, class _Tag, class... _Args>(
             __ignore, _State& __state, _Receiver& __rcvr, _Tag __tag,
             _Args&&... __args) noexcept -> void {
-        STDEXEC_APPLE_CLANG(
-            __state.__self_ == &__state ? void() : std::terminate());
         // Write the tag and the args into the operation state so that we can
         // forward the completion from within the scheduler's execution context.
         if constexpr (__nothrow_callable<__tup::__mktuple_t, _Tag, _Args...>)
diff --git a/include/sdbusplus/async/stdexec/__detail/__schedulers.hpp b/include/sdbusplus/async/stdexec/__detail/__schedulers.hpp
index c60a8ff..3933cf4 100644
--- a/include/sdbusplus/async/stdexec/__detail/__schedulers.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__schedulers.hpp
@@ -108,15 +108,16 @@
 }
 
 template <class _Env>
-    requires tag_invocable<get_delegatee_scheduler_t, const _Env&>
-inline auto get_delegatee_scheduler_t::operator()(const _Env& __env) const
-    noexcept -> tag_invoke_result_t<get_delegatee_scheduler_t, const _Env&>
+    requires tag_invocable<get_delegation_scheduler_t, const _Env&>
+inline auto get_delegation_scheduler_t::operator()(const _Env& __env) const
+    noexcept -> tag_invoke_result_t<get_delegation_scheduler_t, const _Env&>
 {
     static_assert(
-        nothrow_tag_invocable<get_delegatee_scheduler_t, const _Env&>);
+        nothrow_tag_invocable<get_delegation_scheduler_t, const _Env&>);
     static_assert(
-        scheduler<tag_invoke_result_t<get_delegatee_scheduler_t, const _Env&>>);
-    return tag_invoke(get_delegatee_scheduler_t{}, __env);
+        scheduler<
+            tag_invoke_result_t<get_delegation_scheduler_t, const _Env&>>);
+    return tag_invoke(get_delegation_scheduler_t{}, __env);
 }
 
 template <__completion_tag _Tag>
diff --git a/include/sdbusplus/async/stdexec/__detail/__sender_adaptor_closure.hpp b/include/sdbusplus/async/stdexec/__detail/__sender_adaptor_closure.hpp
index 3328e30..1124e60 100644
--- a/include/sdbusplus/async/stdexec/__detail/__sender_adaptor_closure.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__sender_adaptor_closure.hpp
@@ -104,21 +104,62 @@
     STDEXEC_ATTRIBUTE((no_unique_address))
     _Fun __fun_{};
 
+#if STDEXEC_INTELLISENSE()
+    // MSVCBUG
+    // https://developercommunity.visualstudio.com/t/rejects-valid-EDG-invocation-of-lambda/10786020
+
+    template <class _Sender>
+    struct __lambda_rvalue
+    {
+        __binder_back& __self_;
+        _Sender& __sndr_;
+
+        STDEXEC_ATTRIBUTE((host, device, always_inline))
+        auto operator()(_As&... __as) const //
+            noexcept(__nothrow_callable<_Fun, _Sender, _As...>)
+                -> __call_result_t<_Fun, _Sender, _As...>
+        {
+            return static_cast<_Fun&&>(__self_.__fun_)(
+                static_cast<_Sender&&>(__sndr_), static_cast<_As&&>(__as)...);
+        }
+    };
+
+    template <class _Sender>
+    struct __lambda_lvalue
+    {
+        const __binder_back& __self_;
+        _Sender& __sndr_;
+
+        STDEXEC_ATTRIBUTE((host, device, always_inline))
+        auto operator()(const _As&... __as) const //
+            noexcept(__nothrow_callable<const _Fun&, _Sender, const _As&...>)
+                -> __call_result_t<const _Fun&, _Sender, const _As&...>
+        {
+            return __self_.__fun_(static_cast<_Sender&&>(__sndr_), __as...);
+        }
+    };
+#endif
+
     template <sender _Sender>
         requires __callable<_Fun, _Sender, _As...>
     STDEXEC_ATTRIBUTE((host, device, always_inline))
-    __call_result_t<_Fun, _Sender, _As...> operator()(
-        _Sender&& __sndr) && noexcept(__nothrow_callable<_Fun, _Sender, _As...>)
+    auto operator()(_Sender&& __sndr) && //
+        noexcept(__nothrow_callable<_Fun, _Sender, _As...>)
+            -> __call_result_t<_Fun, _Sender, _As...>
     {
+#if STDEXEC_INTELLISENSE()
+        return this->apply(__lambda_rvalue<_Sender>{*this, __sndr}, *this);
+#else
         return this->apply(
-            [&__sndr, this](_As&... __as) noexcept(
-                __nothrow_callable<_Fun, _Sender, _As...>)
+            [&__sndr, this](_As&... __as) //
+            noexcept(__nothrow_callable<_Fun, _Sender, _As...>)
                 -> __call_result_t<_Fun, _Sender, _As...> {
                 return static_cast<_Fun&&>(
                     __fun_)(static_cast<_Sender&&>(__sndr),
                             static_cast<_As&&>(__as)...);
             },
             *this);
+#endif
     }
 
     template <sender _Sender>
@@ -128,13 +169,17 @@
         noexcept(__nothrow_callable<const _Fun&, _Sender, const _As&...>)
             -> __call_result_t<const _Fun&, _Sender, const _As&...>
     {
+#if STDEXEC_INTELLISENSE()
+        return this->apply(__lambda_lvalue<_Sender>{*this, __sndr}, *this);
+#else
         return this->apply(
-            [&__sndr, this](const _As&... __as) noexcept(
-                __nothrow_callable<_Fun, _Sender, const _As&...>)
+            [&__sndr, this](const _As&... __as) //
+            noexcept(__nothrow_callable<const _Fun&, _Sender, const _As&...>)
                 -> __call_result_t<const _Fun&, _Sender, const _As&...> {
                 return __fun_(static_cast<_Sender&&>(__sndr), __as...);
             },
             *this);
+#endif
     }
 };
 } // namespace __closure
diff --git a/include/sdbusplus/async/stdexec/__detail/__senders.hpp b/include/sdbusplus/async/stdexec/__detail/__senders.hpp
index 32c0a77..bfb1c01 100644
--- a/include/sdbusplus/async/stdexec/__detail/__senders.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__senders.hpp
@@ -91,6 +91,7 @@
 struct get_completion_signatures_t
 {
     template <class _Sender, class... _Env>
+        requires(sizeof...(_Env) <= 1)
     static auto __impl()
     {
         // Compute the type of the transformed sender:
diff --git a/include/sdbusplus/async/stdexec/__detail/__shared.hpp b/include/sdbusplus/async/stdexec/__detail/__shared.hpp
index 8e008d6..0922594 100644
--- a/include/sdbusplus/async/stdexec/__detail/__shared.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__shared.hpp
@@ -95,7 +95,8 @@
 template <class _CvrefSender, class _Receiver>
 struct __local_state :
     __local_state_base,
-    __enable_receiver_from_this<_CvrefSender, _Receiver>
+    __enable_receiver_from_this<_CvrefSender, _Receiver,
+                                __local_state<_CvrefSender, _Receiver>>
 {
     using __tag_t = tag_of_t<_CvrefSender>;
     using __stok_t = stop_token_of_t<env_of_t<_Receiver>>;
@@ -228,6 +229,7 @@
     return &__tombstone_;
 }
 
+//! Heap-allocatable shared state for things like `stdexec::split`.
 template <class _CvrefSender, class _Env>
 struct __shared_state :
     private __enable_intrusive_from_this<__shared_state<_CvrefSender, _Env>, 2>
diff --git a/include/sdbusplus/async/stdexec/__detail/__spin_loop_pause.hpp b/include/sdbusplus/async/stdexec/__detail/__spin_loop_pause.hpp
index 7cae36f..bef1fae 100644
--- a/include/sdbusplus/async/stdexec/__detail/__spin_loop_pause.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__spin_loop_pause.hpp
@@ -24,7 +24,7 @@
 
 #if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) ||             \
     defined(_M_IX86)
-#if STDEXEC_MSVC()
+#if STDEXEC_MSVC_HEADERS()
 #include <intrin.h>
 #endif
 namespace stdexec
@@ -32,7 +32,7 @@
 STDEXEC_ATTRIBUTE((always_inline))
 static void __spin_loop_pause() noexcept
 {
-#if STDEXEC_MSVC()
+#if STDEXEC_MSVC_HEADERS()
     _mm_pause();
 #else
     __builtin_ia32_pause();
diff --git a/include/sdbusplus/async/stdexec/__detail/__starts_on.hpp b/include/sdbusplus/async/stdexec/__detail/__starts_on.hpp
new file mode 100644
index 0000000..9478d10
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__starts_on.hpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2021-2024 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__concepts.hpp"
+#include "__diagnostics.hpp"
+#include "__domain.hpp"
+#include "__env.hpp"
+#include "__let.hpp"
+#include "__meta.hpp"
+#include "__schedulers.hpp"
+#include "__senders_core.hpp"
+#include "__tag_invoke.hpp"
+#include "__transform_sender.hpp"
+#include "__utility.hpp"
+
+namespace stdexec
+{
+namespace __detail
+{
+//! Constant function object always returning `__val_`.
+template <class _Ty, class = __name_of<__decay_t<_Ty>>>
+struct __always
+{
+    _Ty __val_;
+
+    auto operator()() noexcept -> _Ty
+    {
+        return static_cast<_Ty&&>(__val_);
+    }
+};
+
+template <class _Ty>
+__always(_Ty) -> __always<_Ty>;
+} // namespace __detail
+
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.adaptors.starts_on]
+namespace __starts_on_ns
+{
+struct starts_on_t
+{
+    using _Sender = __1;
+    using _Scheduler = __0;
+    using __legacy_customizations_t =
+        __types<tag_invoke_t(starts_on_t, _Scheduler, _Sender)>;
+
+    template <scheduler _Scheduler, sender _Sender>
+    auto operator()(_Scheduler&& __sched,
+                    _Sender&& __sndr) const -> __well_formed_sender auto
+    {
+        auto __domain = query_or(get_domain, __sched, default_domain());
+        return stdexec::transform_sender(
+            __domain,
+            __make_sexpr<starts_on_t>(static_cast<_Scheduler&&>(__sched),
+                                      static_cast<_Sender&&>(__sndr)));
+    }
+
+    template <class _Env>
+    STDEXEC_ATTRIBUTE((always_inline))
+    static auto __transform_env_fn(_Env&& __env) noexcept
+    {
+        return [&](__ignore, auto __sched, __ignore) noexcept {
+            return __detail::__mkenv_sched(static_cast<_Env&&>(__env), __sched);
+        };
+    }
+
+    template <class _Sender, class _Env>
+    static auto transform_env(const _Sender& __sndr, _Env&& __env) noexcept
+    {
+        return __sexpr_apply(__sndr,
+                             __transform_env_fn(static_cast<_Env&&>(__env)));
+    }
+
+    template <class _Sender, class _Env>
+    static auto transform_sender(_Sender&& __sndr, const _Env&)
+    {
+        return __sexpr_apply(
+            static_cast<_Sender&&>(__sndr),
+            []<class _Data, class _Child>(__ignore, _Data&& __data,
+                                          _Child&& __child) {
+                // This is the heart of starts_on: It uses `let_value` to
+                // schedule `__child` on the given scheduler:
+                return let_value(
+                    schedule(__data),
+                    __detail::__always{static_cast<_Child&&>(__child)});
+            });
+    }
+};
+} // namespace __starts_on_ns
+
+using __starts_on_ns::starts_on_t;
+inline constexpr starts_on_t starts_on{};
+
+using on_t = starts_on_t;
+inline constexpr starts_on_t on{};
+
+using start_on_t = starts_on_t;
+inline constexpr starts_on_t start_on{};
+
+template <>
+struct __sexpr_impl<starts_on_t> : __sexpr_defaults
+{
+    static constexpr auto get_completion_signatures = //
+        []<class _Sender>(_Sender&&) noexcept         //
+        -> __completion_signatures_of_t<              //
+            transform_sender_result_t<default_domain, _Sender, empty_env>> {
+        return {};
+    };
+};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__sync_wait.hpp b/include/sdbusplus/async/stdexec/__detail/__sync_wait.hpp
index 9032a3e..122dd5a 100644
--- a/include/sdbusplus/async/stdexec/__detail/__sync_wait.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__sync_wait.hpp
@@ -55,8 +55,8 @@
         return __loop_->get_scheduler();
     }
 
-    auto
-        query(get_delegatee_scheduler_t) const noexcept -> run_loop::__scheduler
+    auto query(get_delegation_scheduler_t) const noexcept
+        -> run_loop::__scheduler
     {
         return __loop_->get_scheduler();
     }
@@ -203,7 +203,7 @@
                                   __q<__too_many_successful_completions_error>>,
                    _Sender, __env>>;
 
-#if STDEXEC_NVHPC()
+#if STDEXEC_EDG()
 // It requires some hoop-jumping to get the NVHPC compiler to report a
 // meaningful diagnostic for SFINAE failures.
 template <class _Sender>
@@ -263,7 +263,7 @@
                                      static_cast<_Sender&&>(__sndr));
     }
 
-#if STDEXEC_NVHPC()
+#if STDEXEC_EDG()
     // 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
@@ -286,7 +286,7 @@
       /// `sync_wait` connects and starts the given sender, and then drives a
       ///         `run_loop` instance until the sender completes. Additional work
       ///         can be delegated to the `run_loop` by scheduling work on the
-      ///         scheduler returned by calling `get_delegatee_scheduler` on the
+      ///         scheduler returned by calling `get_delegation_scheduler` on the
       ///         receiver's environment.
       ///
       /// @pre The sender must have a exactly one value completion signature. That
@@ -308,22 +308,23 @@
     auto apply_sender(_Sender&& __sndr) const
         -> std::optional<__sync_wait_result_t<_Sender>>
     {
-        __state __local{};
+        __state __local_state{};
         std::optional<__sync_wait_result_t<_Sender>> __result{};
 
         // Launch the sender with a continuation that will fill in the __result
-        // optional or set the exception_ptr in __local.
-        auto __op_state = connect(static_cast<_Sender&&>(__sndr),
-                                  __receiver_t<_Sender>{&__local, &__result});
+        // optional or set the exception_ptr in __local_state.
+        auto __op_state =
+            connect(static_cast<_Sender&&>(__sndr),
+                    __receiver_t<_Sender>{&__local_state, &__result});
         stdexec::start(__op_state);
 
         // Wait for the variant to be filled in.
-        __local.__loop_.run();
+        __local_state.__loop_.run();
 
-        if (__local.__eptr_)
+        if (__local_state.__eptr_)
         {
             std::rethrow_exception(
-                static_cast<std::exception_ptr&&>(__local.__eptr_));
+                static_cast<std::exception_ptr&&>(__local_state.__eptr_));
         }
 
         return __result;
@@ -353,7 +354,7 @@
                                      static_cast<_Sender&&>(__sndr));
     }
 
-#if STDEXEC_NVHPC()
+#if STDEXEC_EDG()
     template <class _Sender, class _Error = __error_description_t<
                                  __result_of<into_variant, _Sender>>>
     auto operator()(_Sender&&, [[maybe_unused]] _Error __diagnostic = {}) const
diff --git a/include/sdbusplus/async/stdexec/__detail/__transfer_just.hpp b/include/sdbusplus/async/stdexec/__detail/__transfer_just.hpp
index fe189b1..682ee61 100644
--- a/include/sdbusplus/async/stdexec/__detail/__transfer_just.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__transfer_just.hpp
@@ -20,7 +20,7 @@
 // include these after __execution_fwd.hpp
 #include "__basic_sender.hpp"
 #include "__concepts.hpp"
-#include "__continue_on.hpp"
+#include "__continues_on.hpp"
 #include "__domain.hpp"
 #include "__env.hpp"
 #include "__just.hpp"
@@ -55,8 +55,8 @@
 {
     return [&]<class _Scheduler, class... _Values>(_Scheduler&& __sched,
                                                    _Values&&... __vals) {
-        return continue_on(just(static_cast<_Values&&>(__vals)...),
-                           static_cast<_Scheduler&&>(__sched));
+        return continues_on(just(static_cast<_Values&&>(__vals)...),
+                            static_cast<_Scheduler&&>(__sched));
     };
 }
 
diff --git a/include/sdbusplus/async/stdexec/__detail/__tuple.hpp b/include/sdbusplus/async/stdexec/__detail/__tuple.hpp
index 63c79b2..3c5f2d2 100644
--- a/include/sdbusplus/async/stdexec/__detail/__tuple.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__tuple.hpp
@@ -58,6 +58,18 @@
 template <std::size_t... _Is, __indices<_Is...> _Idx, class... _Ts>
 struct __tuple<_Idx, _Ts...> : __box<_Ts, _Is>...
 {
+    template <class... _Us>
+    static __tuple __convert_from(__tuple<_Idx, _Us...>&& __tup)
+    {
+        return __tuple{{static_cast<_Us&&>(__tup.__box<_Us, _Is>::__value)}...};
+    }
+
+    template <class... _Us>
+    static __tuple __convert_from(const __tuple<_Idx, _Us...>& __tup)
+    {
+        return __tuple{{__tup.__box<_Us, _Is>::__value}...};
+    }
+
     template <class _Fn, class _Self, class... _Us>
     STDEXEC_ATTRIBUTE((host, device, always_inline))
     static auto apply(_Fn&& __fn, _Self&& __self, _Us&&... __us) //
diff --git a/include/sdbusplus/async/stdexec/__detail/__type_traits.hpp b/include/sdbusplus/async/stdexec/__detail/__type_traits.hpp
index 41a17c7..8c6cc67 100644
--- a/include/sdbusplus/async/stdexec/__detail/__type_traits.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__type_traits.hpp
@@ -31,10 +31,23 @@
 // __decay_t: An efficient implementation for std::decay
 #if STDEXEC_HAS_BUILTIN(__decay)
 
-template <class _Ty>
-using __decay_t = __decay(_Ty);
+namespace __tt
+{
+template <class>
+struct __wrap;
 
-#elif STDEXEC_NVHPC()
+template <bool>
+struct __decay_
+{
+    template <class _Ty>
+    using __f = __decay(_Ty);
+};
+} // namespace __tt
+template <class _Ty>
+using __decay_t = typename __tt::__decay_<sizeof(__tt::__wrap<_Ty>*) ==
+                                          ~0ul>::template __f<_Ty>;
+
+#elif STDEXEC_EDG()
 
 template <class _Ty>
 using __decay_t = std::decay_t<_Ty>;
diff --git a/include/sdbusplus/async/stdexec/__detail/__variant.hpp b/include/sdbusplus/async/stdexec/__detail/__variant.hpp
index a3ea4bd..b49e4cf 100644
--- a/include/sdbusplus/async/stdexec/__detail/__variant.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__variant.hpp
@@ -138,7 +138,7 @@
         __destroy();
         ::new (__storage_) _Ty{static_cast<_As&&>(__as)...};
         __index_ = __new_index;
-        return *reinterpret_cast<_Ty*>(__storage_);
+        return *std::launder(reinterpret_cast<_Ty*>(__storage_));
     }
 
     template <std::size_t _Ny, class... _As>
@@ -151,11 +151,26 @@
         __destroy();
         ::new (__storage_) __at<_Ny>{static_cast<_As&&>(__as)...};
         __index_ = _Ny;
-        return *reinterpret_cast<__at<_Ny>*>(__storage_);
+        return *std::launder(reinterpret_cast<__at<_Ny>*>(__storage_));
+    }
+
+    template <std::size_t _Ny, class _Fn, class... _As>
+    STDEXEC_ATTRIBUTE((host, device))
+    __at<_Ny>& emplace_from_at(_Fn&& __fn, _As&&... __as) //
+        noexcept(__nothrow_callable<_Fn, _As...>)
+    {
+        static_assert(__same_as<__call_result_t<_Fn, _As...>, __at<_Ny>>,
+                      "callable does not return the correct type");
+
+        __destroy();
+        ::new (__storage_)
+            __at<_Ny>(static_cast<_Fn&&>(__fn)(static_cast<_As&&>(__as)...));
+        __index_ = _Ny;
+        return *std::launder(reinterpret_cast<__at<_Ny>*>(__storage_));
     }
 
     template <class _Fn, class... _As>
-    STDEXEC_ATTRIBUTE((host, device))
+    STDEXEC_ATTRIBUTE((host, device, always_inline))
     auto emplace_from(_Fn&& __fn, _As&&... __as) //
         noexcept(__nothrow_callable<_Fn, _As...>)
             -> __call_result_t<_Fn, _As...>&
@@ -164,12 +179,8 @@
         constexpr std::size_t __new_index =
             stdexec::__index_of<__result_t, _Ts...>();
         static_assert(__new_index != __variant_npos, "Type not in variant");
-
-        __destroy();
-        ::new (__storage_)
-            __result_t(static_cast<_Fn&&>(__fn)(static_cast<_As&&>(__as)...));
-        __index_ = __new_index;
-        return *reinterpret_cast<__result_t*>(__storage_);
+        return emplace_from_at<__new_index>(static_cast<_Fn&&>(__fn),
+                                            static_cast<_As&&>(__as)...);
     }
 
     template <class _Fn, class _Self, class... _As>
diff --git a/include/sdbusplus/async/stdexec/__detail/__when_all.hpp b/include/sdbusplus/async/stdexec/__detail/__when_all.hpp
index 83bbe59..29e373b 100644
--- a/include/sdbusplus/async/stdexec/__detail/__when_all.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__when_all.hpp
@@ -21,7 +21,7 @@
 #include "../stop_token.hpp"
 #include "__basic_sender.hpp"
 #include "__concepts.hpp"
-#include "__continue_on.hpp"
+#include "__continues_on.hpp"
 #include "__diagnostics.hpp"
 #include "__domain.hpp"
 #include "__env.hpp"
@@ -206,7 +206,7 @@
     template <class _Receiver>
     void __arrive(_Receiver& __rcvr) noexcept
     {
-        if (0 == --__count_)
+        if (1 == __count_.fetch_sub(1))
         {
             __complete(__rcvr);
         }
@@ -410,7 +410,7 @@
         {
             // We only need to bother recording the completion values
             // if we're not already in the "error" or "stopped" state.
-            if (__state.__state_ == __started)
+            if (__state.__state_.load() == __started)
             {
                 auto& __opt_values = __tup::get<__v<_Index>>(__state.__values_);
                 using _Tuple = __decayed_tuple<_Args...>;
@@ -527,7 +527,7 @@
             static_cast<_Sender&&>(__sndr),
             [&]<class _Data, class... _Child>(__ignore, _Data&& __data,
                                               _Child&&... __child) {
-                return continue_on(
+                return continues_on(
                     when_all_t()(static_cast<_Child&&>(__child)...),
                     get_completion_scheduler<set_value_t>(__data));
             });
diff --git a/include/sdbusplus/async/stdexec/async_scope.hpp b/include/sdbusplus/async/stdexec/async_scope.hpp
index 6482366..67b223d 100644
--- a/include/sdbusplus/async/stdexec/async_scope.hpp
+++ b/include/sdbusplus/async/stdexec/async_scope.hpp
@@ -16,6 +16,7 @@
 #pragma once
 
 #include "../stdexec/__detail/__intrusive_queue.hpp"
+#include "../stdexec/__detail/__optional.hpp"
 #include "../stdexec/execution.hpp"
 #include "../stdexec/stop_token.hpp"
 #include "env.hpp"
@@ -181,13 +182,13 @@
             auto& __active = __scope->__active_;
             if (--__active == 0)
             {
-                auto __local = std::move(__scope->__waiters_);
+                auto __local_waiters = std::move(__scope->__waiters_);
                 __guard.unlock();
                 __scope = nullptr;
                 // do not access __scope
-                while (!__local.empty())
+                while (!__local_waiters.empty())
                 {
-                    auto* __next = __local.pop_front();
+                    auto* __next = __local_waiters.pop_front();
                     __next->__notify_waiter(__next);
                     // __scope must be considered deleted
                 }
@@ -371,6 +372,7 @@
         {
             try
             {
+                __forward_consumer_.reset();
                 auto __state = std::move(__state_);
                 STDEXEC_ASSERT(__state != nullptr);
                 std::unique_lock __guard{__state->__mutex_};
@@ -423,7 +425,7 @@
         _Receiver __rcvr_;
         std::unique_ptr<__future_state<_Sender, _Env>> __state_;
         STDEXEC_ATTRIBUTE((no_unique_address))
-        __forward_consumer __forward_consumer_;
+        stdexec::__optional<__forward_consumer> __forward_consumer_;
 
       public:
         using __id = __future_op;
@@ -455,7 +457,7 @@
                            }},
             __rcvr_(static_cast<_Receiver2&&>(__rcvr)),
             __state_(std::move(__state)),
-            __forward_consumer_(get_stop_token(get_env(__rcvr_)),
+            __forward_consumer_(std::in_place, get_stop_token(get_env(__rcvr_)),
                                 __forward_stopped{&__state_->__stop_source_})
         {}
 
@@ -486,7 +488,7 @@
     };
 };
 
-#if STDEXEC_NVHPC()
+#if STDEXEC_EDG()
 template <class _Fn>
 struct __completion_as_tuple2_;
 
@@ -592,7 +594,8 @@
     }
 
     inplace_stop_source __stop_source_;
-    std::optional<inplace_stop_callback<__forward_stopped>> __forward_scope_;
+    stdexec::__optional<inplace_stop_callback<__forward_stopped>>
+        __forward_scope_;
     std::mutex __mutex_;
     __future_step __step_ = __future_step::__created;
     std::unique_ptr<__future_state_base, __dynamic_delete<__future_state_base>>
@@ -614,12 +617,11 @@
         __future_state_base<_Completions, _Env>* __state_;
         const __impl* __scope_;
 
-        void __dispatch_result_() noexcept
+        void __dispatch_result_(std::unique_lock<std::mutex>& __guard) noexcept
         {
             auto& __state = *__state_;
-            std::unique_lock __guard{__state.__mutex_};
-            auto __local = std::move(__state.__subscribers_);
-            __state.__forward_scope_ = std::nullopt;
+            auto __local_subscribers = std::move(__state.__subscribers_);
+            __state.__forward_scope_.reset();
             if (__state.__no_future_.get() != nullptr)
             {
                 // nobody is waiting for the results
@@ -631,24 +633,22 @@
                 return;
             }
             __guard.unlock();
-            while (!__local.empty())
+            while (!__local_subscribers.empty())
             {
-                auto* __sub = __local.pop_front();
+                auto* __sub = __local_subscribers.pop_front();
                 __sub->__complete();
             }
         }
 
         template <class _Tag, class... _As>
-        bool __save_completion(_Tag, _As&&... __as) noexcept
+        void __save_completion(_Tag, _As&&... __as) noexcept
         {
             auto& __state = *__state_;
             try
             {
-                std::unique_lock __guard{__state.__mutex_};
                 using _Tuple = __decayed_std_tuple<_Tag, _As...>;
                 __state.__data_.template emplace<_Tuple>(
                     _Tag(), static_cast<_As&&>(__as)...);
-                return true;
             }
             catch (...)
             {
@@ -656,33 +656,32 @@
                 __state.__data_.template emplace<_Tuple>(
                     set_error_t(), std::current_exception());
             }
-            return false;
         }
 
         template <__movable_value... _As>
         void set_value(_As&&... __as) noexcept
         {
-            if (__save_completion(set_value_t(), static_cast<_As&&>(__as)...))
-            {
-                __dispatch_result_();
-            }
+            auto& __state = *__state_;
+            std::unique_lock __guard{__state.__mutex_};
+            __save_completion(set_value_t(), static_cast<_As&&>(__as)...);
+            __dispatch_result_(__guard);
         }
 
         template <__movable_value _Error>
         void set_error(_Error&& __err) noexcept
         {
-            if (__save_completion(set_error_t(), static_cast<_Error&&>(__err)))
-            {
-                __dispatch_result_();
-            }
+            auto& __state = *__state_;
+            std::unique_lock __guard{__state.__mutex_};
+            __save_completion(set_error_t(), static_cast<_Error&&>(__err));
+            __dispatch_result_(__guard);
         }
 
         void set_stopped() noexcept
         {
-            if (__save_completion(set_stopped_t()))
-            {
-                __dispatch_result_();
-            }
+            auto& __state = *__state_;
+            std::unique_lock __guard{__state.__mutex_};
+            __save_completion(set_stopped_t());
+            __dispatch_result_(__guard);
         }
 
         auto get_env() const noexcept -> const __env_t<_Env>&
@@ -927,8 +926,8 @@
         // start is noexcept so we can assume that the operation will complete
         // after this, which means we can rely on its self-ownership to ensure
         // that it is eventually deleted
-        stdexec::start(*new __op_t{nest(static_cast<_Sender&&>(__sndr)),
-                                   static_cast<_Env&&>(__env), &__impl_});
+        stdexec::start(*(new __op_t{nest(static_cast<_Sender&&>(__sndr)),
+                                    static_cast<_Env&&>(__env), &__impl_}));
     }
 
     template <__movable_value _Env = empty_env,
diff --git a/include/sdbusplus/async/stdexec/at_coroutine_exit.hpp b/include/sdbusplus/async/stdexec/at_coroutine_exit.hpp
index dac8f8b..28b5a51 100644
--- a/include/sdbusplus/async/stdexec/at_coroutine_exit.hpp
+++ b/include/sdbusplus/async/stdexec/at_coroutine_exit.hpp
@@ -151,9 +151,15 @@
   public:
     using promise_type = __promise;
 
+#if STDEXEC_EDG()
+    __task(__coro::coroutine_handle<__promise> __coro) noexcept :
+        __coro_(__coro)
+    {}
+#else
     explicit __task(__coro::coroutine_handle<__promise> __coro) noexcept :
         __coro_(__coro)
     {}
+#endif
 
     __task(__task&& __that) noexcept :
         __coro_(std::exchange(__that.__coro_, {}))
@@ -214,9 +220,15 @@
 
     struct __promise : with_awaitable_senders<__promise>
     {
+#if STDEXEC_EDG()
+        template <class _Action>
+        __promise(_Action&&, _Ts&&... __ts) noexcept : __args_{__ts...}
+        {}
+#else
         template <class _Action>
         explicit __promise(_Action&&, _Ts&... __ts) noexcept : __args_{__ts...}
         {}
+#endif
 
         auto initial_suspend() noexcept -> __coro::suspend_always
         {
diff --git a/include/sdbusplus/async/stdexec/commit.info b/include/sdbusplus/async/stdexec/commit.info
index e3aca22..349afcb 100644
--- a/include/sdbusplus/async/stdexec/commit.info
+++ b/include/sdbusplus/async/stdexec/commit.info
@@ -1 +1 @@
-439a29175f45aecdec6b124e75dc3c7bc5d8b778
+c3f90d40a3d4a596e44cc115e2249a2eeb6fcde0
diff --git a/include/sdbusplus/async/stdexec/coroutine.hpp b/include/sdbusplus/async/stdexec/coroutine.hpp
index 2426ed3..e9d3439 100644
--- a/include/sdbusplus/async/stdexec/coroutine.hpp
+++ b/include/sdbusplus/async/stdexec/coroutine.hpp
@@ -18,7 +18,7 @@
 #include "__detail/__awaitable.hpp"
 #include "__detail/__config.hpp"
 
-#if STDEXEC_MSVC() && _MSC_VER >= 1939
+#if STDEXEC_MSVC() && _MSC_VER <= 1939
 namespace stdexec
 {
 // MSVCBUG
diff --git a/include/sdbusplus/async/stdexec/execution.hpp b/include/sdbusplus/async/stdexec/execution.hpp
index 0dc3800..65956d4 100644
--- a/include/sdbusplus/async/stdexec/execution.hpp
+++ b/include/sdbusplus/async/stdexec/execution.hpp
@@ -23,7 +23,7 @@
 #include "__detail/__bulk.hpp"
 #include "__detail/__completion_signatures.hpp"
 #include "__detail/__connect_awaitable.hpp"
-#include "__detail/__continue_on.hpp"
+#include "__detail/__continues_on.hpp"
 #include "__detail/__cpo.hpp"
 #include "__detail/__debug.hpp"
 #include "__detail/__domain.hpp"
@@ -49,7 +49,7 @@
 #include "__detail/__senders.hpp"
 #include "__detail/__split.hpp"
 #include "__detail/__start_detached.hpp"
-#include "__detail/__start_on.hpp"
+#include "__detail/__starts_on.hpp"
 #include "__detail/__stopped_as_error.hpp"
 #include "__detail/__stopped_as_optional.hpp"
 #include "__detail/__submit.hpp"
diff --git a/include/sdbusplus/async/stdexec/task.hpp b/include/sdbusplus/async/stdexec/task.hpp
index 1f8a038..a6ce255 100644
--- a/include/sdbusplus/async/stdexec/task.hpp
+++ b/include/sdbusplus/async/stdexec/task.hpp
@@ -429,9 +429,10 @@
         {
             // TODO: If we have a complete-where-it-starts query then we can
             // optimize this to avoid the reschedule
-            return as_awaitable(transfer(static_cast<_Awaitable&&>(__awaitable),
-                                         get_scheduler(*__context_)),
-                                *this);
+            return as_awaitable(
+                continues_on(static_cast<_Awaitable&&>(__awaitable),
+                             get_scheduler(*__context_)),
+                *this);
         }
 
         template <class _Scheduler>
diff --git a/include/sdbusplus/async/timer.hpp b/include/sdbusplus/async/timer.hpp
index 3a88cdf..47032e5 100644
--- a/include/sdbusplus/async/timer.hpp
+++ b/include/sdbusplus/async/timer.hpp
@@ -104,7 +104,8 @@
         // Run the delay sender and then switch back to the worker thread.
         // The delay completion happens from the sd-event handler, which is
         // ran on the 'caller' thread.
-        return execution::transfer(sleep_sender(ctx, time), get_scheduler(ctx));
+        return execution::continues_on(sleep_sender(ctx, time),
+                                       get_scheduler(ctx));
     }
 
   private:
diff --git a/src/async/context.cpp b/src/async/context.cpp
index 96535fa..17ec7ce 100644
--- a/src/async/context.cpp
+++ b/src/async/context.cpp
@@ -103,8 +103,8 @@
     {
         // Handle the next sdbus event.  Completion likely happened on a
         // different thread so we need to transfer back to the worker thread.
-        co_await execution::transfer(wait_process_sender(ctx),
-                                     ctx.loop.get_scheduler());
+        co_await execution::continues_on(wait_process_sender(ctx),
+                                         ctx.loop.get_scheduler());
     }
 
     {