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.
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.
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.