-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Allow promises to be constructed for non-default-constructible types #2568
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
Allow promises to be constructed for non-default-constructible types #2568
Conversation
f90ef17 to
042e51f
Compare
042e51f to
47e5e09
Compare
StephanTLavavej
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for fixing this long-standing bug! (I can't count how many times it's been reported over the years, but it's definitely "lots".) Main feedback here is a request for test coverage, plus minor codebase convention nitpicks. Your strategy looks good to me and it should preserve binary compatibility.
|
I've also (re)discovered this bug: Lines 265 to 275 in afe0800
Also seen here: https://stackoverflow.com/a/42648634 Since The fix would be a breaking change. I could have it fixed only with the new behaviour, or have the new behaviour follow the old behaviour in this edge case and just add a comment that it needs to be fixed. |
This comment was marked as resolved.
This comment was marked as resolved.
StephanTLavavej
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test looks good, thank you! One more set of small comments (the most significant being the Standard citation, which isn't very significant) and I think this will be ready to go 🚀
tests/std/tests/GH_002488_promise_not_default_constructible_types/test.cpp
Show resolved
Hide resolved
tests/std/tests/GH_002488_promise_not_default_constructible_types/test.cpp
Outdated
Show resolved
Hide resolved
tests/std/tests/GH_002488_promise_not_default_constructible_types/test.cpp
Show resolved
Hide resolved
tests/std/tests/GH_002488_promise_not_default_constructible_types/test.cpp
Outdated
Show resolved
Hide resolved
tests/std/tests/GH_002488_promise_not_default_constructible_types/test.cpp
Outdated
Show resolved
Hide resolved
tests/std/tests/GH_002488_promise_not_default_constructible_types/test.cpp
Outdated
Show resolved
Hide resolved
tests/std/tests/GH_002488_promise_not_default_constructible_types/test.cpp
Show resolved
Hide resolved
tests/std/tests/GH_002488_promise_not_default_constructible_types/test.cpp
Outdated
Show resolved
Hide resolved
tests/std/tests/GH_002488_promise_not_default_constructible_types/test.cpp
Outdated
Show resolved
Hide resolved
|
I've pushed a merge with |
|
I'm mirroring this to the MSVC-internal repo - please notify me if any further changes are pushed. |
|
Thanks again for fixing this long-standing bug, and congratulations on your first microsoft/STL commit! 🎉 🚀 😻 This will ship in VS 2022 17.2 Preview 3. |
A fix for #2488 without breaking ABI compatibility.
For types that are not default constructible,
promise<T>will now act like it was supposed to all along (set_valuewill copy/move construct a value rather than copy/move assign it). The value is stored like a std::optional, where_Has_stored_resultis repurposed to be "has a value been constructed", and its old purpose is replaced with_Has_stored_result || (_Exception != nullptr).Differences are guarded with
is_default_constructible<_Ty>to have the same behaviour as before, except thatpromise<T>::set_exception(nullptr)has been explicitly disallowed (It was already UB, since a precondition ofset_exception_ptr/set_exception_at_thread_exitis "pis not null.", and would makegetreturn a default constructed value).I also removed a member function
void _Set_value(bool _At_thread_exit);that had the comment// store a (void) resultand its corresponding_Set_value_rawfunction, since they were unused and it would be a logical error to call them with a non-default-constructible type.In vNext,
promise<T>can be fixed for all types by replacing all theis_default_constructible<_Ty>checks withfalse.