-
Notifications
You must be signed in to change notification settings - Fork 190
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
let_value decay-copies its final result #556
Comments
Good find! Lvalue refs are indeed proving to be a challenge. I originally thought the same trick with
One possible solution is to decay copy each |
I asked whether the stdexec implementation of I'm a little bit worried about deferring destruction of the successor operation to the destructor of the |
I have a local change that makes the above-described unit test build and pass, but I'm finding more problems elsewhere that I haven't minimized, yet. I'll publish a |
This diff addresses #556 by deferring the destruction of `let_value`'s successor operation state to the destruction of the whole operation state, which allows us to safely perfectly forward references without a decay-copy.
* Fix lvalue ref handling in let_value This diff addresses #556 by deferring the destruction of `let_value`'s successor operation state to the destruction of the whole operation state, which allows us to safely perfectly forward references without a decay-copy. * Fix up predecessor error handling The predecessor _Receiver_ needed updating to match the new clean-up strategy; I should add some test cases to validate these changes. * Add test coverage Add some asserts and new test cases; I confirmed that all the new asserts are executed by at least one test in the suite by inverting each one and witness the resulting crash. * Fix gcc build gcc doesn't seem to like the way I was asking for the address of the expectd cleanup operation in the successor receiver; this diff does the same thing in a way that makes gcc happy. * Try to fix MSVC Looks like MSVC doesn't like it when we pass just_done() to let_value; let's try just_void_or_done() to see if that helps.
This particular issue is fixed with PR #557. We'll have to file follow-up issues for the other algorithms that have similar bugs. |
See discussion on #545 where I discovered the problem. The successor receiver in
let_value
tries to protect itself against the successor invokingset_value
(and, incidentally,set_error
) with a reference to a value that lives in the successor operation state by decay-copyingset_value
's arguments onto the stack, which breakslet_value
's contract with its receiver iflet_value
has advertised that it's going to produce lvalue references; if we're going to distinguish between producing rvalue references and producing values, it breaks the contract when we've promised rvalue references, too, since the result object identities change.Copying from my comment on #545, this test in
finally_test.cpp
repros the build error:The problem is this decay-copy in
let_value
:The
let_value
in the new test case is advertising that it produces aconst int&
but then it producesint
/int&&
.The text was updated successfully, but these errors were encountered: