NVIDIA/stdexec

deleted function in tuple/optional

Closed this issue · 4 comments

i have just upgraded to the latest commit and getting some compiler errors:

stdexec/__detail/__tuple.hpp:56:12: Fehler: gelöschte Funktion »stdexec::__tup::__box<stdexec::__opt::__optional<stdexec::__tup::__tuple<0> >, 2>::__box(stdexec::__tup::__box<stdexec::__opt::__optional<stdexec::__tup::__tuple<0> >, 2>&&)« wird verwendet
stdexec/__detail/__tuple.hpp:28:12: Note: »stdexec::__tup::__box<stdexec::__opt::__optional<stdexec::__tup::__tuple<0> >, 2>::__box(stdexec::__tup::__box<stdexec::__opt::__optional<stdexec::__tup::__tuple<0> >, 2>&&)« is implicitly deleted, as the standard definition would be invalid:
[build]    28 |     struct __box {
stdexec/__detail/__optional.hpp:55:7: Anmerkung: hier deklariert
[build]    55 |       __optional(__optional&&) = delete; // immovable for simplicity's sake

lf I'm going back to 4cffa37 it compiles again.

compiler: gcc 14

Can you share how to repo the problem?

@ericniebler I was just in the process of preparing an example, but unfortunately I didn't have time yesterday. I was able to reduce it to the following example.

https://godbolt.org/z/ssab658Ke

Replacing __optional with std::optional at line 161 in __when_all.hpp fix it in my case.

FWIW, this only seems to be an issue with GCC 12-14 (GCC 11 is fine in CI, 12-14 are not tested?). clang likewise seems to be fine with any version. stdexec::sync_wait(stdexec::when_all(stdexec::just())); is sufficient to reproduce the issue.

If __optional is to stay immovable, the following gets things compiling and tests passing:

diff --git a/include/stdexec/__detail/__when_all.hpp b/include/stdexec/__detail/__when_all.hpp
index 954be76d..29124b57 100644
--- a/include/stdexec/__detail/__when_all.hpp
+++ b/include/stdexec/__detail/__when_all.hpp
@@ -238,13 +238,7 @@ namespace stdexec {
         using _ErrorsVariant = typename _Traits::__errors_variant;
         using _ValuesTuple = typename _Traits::__values_tuple;
         using _State = __when_all_state<_ErrorsVariant, _ValuesTuple, stop_token_of_t<_Env>>;
-        return _State{
-          sizeof...(_Child),
-          inplace_stop_source{},
-          __started,
-          _ErrorsVariant{},
-          _ValuesTuple{},
-          __nullopt};
+        return _State{.__count_{sizeof...(_Child)}};
       };
     }

Since everything except the count are initialized to the same as the defaults, leaving them out should be fine and, curiously, avoids the issue. I'm really not sure what guarantees there are on aggregate initialization there, i.e. if GCC is wrong or right to use a move constructor there for the optional.

If that looks like an acceptable fix I can open a PR?