Interaction with passing lvalue to set_value when sender sends a value
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 2.4k
- Forks
- 270
- Avg merge
- 3d 6h
- Merged PRs (30d)
- 39
Description
In the sample code below, compiling with gcc-13 ( g++-13 -std=c++20 set_value.cpp -I stdexec/include -c), my bespoke sender claims it completes with set_value_t(int), although the implementation ends up sending an lvalue v, an int declared on the stack.
#include <stdexec/execution.hpp>
#include <exec/finally.hpp>
struct StdexecSender {
using is_sender = void;
template <class Receiver>
struct Operation {
Receiver r;
friend auto tag_invoke(stdexec::start_t, Operation& self) noexcept {
int v = 0;
stdexec::set_value((Receiver&&)self.r, v);
};
};
template <class Self, class Receiver>
requires (std::same_as<StdexecSender, std::remove_cv_t<Self>>)
friend auto tag_invoke(stdexec::connect_t, Self&& self, Receiver&& r) {
return Operation<std::decay_t<Receiver>>(std::forward<Receiver>(r));
}
using completion_signatures = stdexec::completion_signatures<stdexec::set_value_t(int)>;
};
static_assert(stdexec::sender<StdexecSender>);
void foo() {
stdexec::sync_wait(exec::finally(stdexec::let_value(StdexecSender{}, [](auto&&...) { return StdexecSender{}; }), stdexec::just()));
}
I get the following diagnostic.
./stdexec/include/exec/../stdexec/execution.hpp:1010:38: warning: 'void stdexec::__debug::_ATTENTION_() [with _Warning = stdexec::_WARNING_<_COMPLETION_SIGNATURES_MISMATCH_, _COMPLETION_SIGNATURE_<stdexec::__receivers::set_value_t(int&)>, _IS_NOT_ONE_OF_<stdexec::__receivers::set_error_t(std::__exception_ptr::exception_ptr), stdexec::__receivers::set_value_t(int)>, _SIGNAL_SENT_BY_SENDER_<stdexec::__let::__sender<stdexec::_Yp<StdexecSender>, main()::<lambda(auto:86&& ...)>, stdexec::__let::let_value_t> > >]' is 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. [-Wdeprecated-declarations]
The key part is
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.
This makes sense given that technically, I should be sending std::move(v) or something of that nature. That said, the lvalue v is convertible to a plain value (I'm not sure what the type category is called here). My understanding is that set_value is akin to returning from a function. A function declared returning int can write return v - should I be able to write set_value(v) here?
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the diagnostic with the reported gcc-13 command and sample set_value.cpp, then inspect stdexec/include/stdexec/execution.hpp around completion-signature checking. Determine the expected treatment of an lvalue passed to set_value when the sender declares set_value_t(int), and add coverage demonstrating the agreed behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- backend-api-design
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100