mirror of
https://github.com/facebook/sapling.git
synced 2024-10-04 22:07:44 +03:00
utils: handle void lambda in ImmediateFuture
Summary: Lambda returning no values would cause the compiler to try to instantiate an ImmediateFuture<void>, which doesn't compile. We could try special casing the void type, but it's easier if we simply consider these lambda to return unit. Reviewed By: genevievehelsel Differential Revision: D28372253 fbshipit-source-id: 1368ae5dc5e2d4d6a5c3e31bc87ed7d230027c3a
This commit is contained in:
parent
3eb9e86b61
commit
de6ca0c970
@ -28,13 +28,21 @@ ImmediateFuture<detail::continuation_result_t<Func, folly::Try<T>>>
|
||||
ImmediateFuture<T>::thenTry(Func&& func) && {
|
||||
using NewType = detail::continuation_result_t<Func, folly::Try<T>>;
|
||||
using RetType = ImmediateFuture<NewType>;
|
||||
using FuncRetType = std::invoke_result_t<Func, folly::Try<T>>;
|
||||
|
||||
return std::visit(
|
||||
[func = std::forward<Func>(func)](auto&& inner) mutable -> RetType {
|
||||
using Type = std::decay_t<decltype(inner)>;
|
||||
if constexpr (std::is_same_v<Type, folly::Try<T>>) {
|
||||
try {
|
||||
return func(std::move(inner));
|
||||
// In the case where Func returns void, force the return value to
|
||||
// be folly::unit.
|
||||
if constexpr (std::is_same_v<FuncRetType, void>) {
|
||||
func(std::move(inner));
|
||||
return folly::unit;
|
||||
} else {
|
||||
return func(std::move(inner));
|
||||
}
|
||||
} catch (std::exception& ex) {
|
||||
return folly::Try<NewType>(
|
||||
folly::exception_wrapper(std::current_exception(), ex));
|
||||
@ -44,8 +52,6 @@ ImmediateFuture<T>::thenTry(Func&& func) && {
|
||||
// transform that return value into a SemiFuture so that the return
|
||||
// type is a SemiFuture<NewType> and not a
|
||||
// SemiFuture<ImmediateFuture<NewType>>.
|
||||
using FuncRetType = std::invoke_result_t<Func, folly::Try<T>>;
|
||||
|
||||
auto semiFut = std::move(inner).defer(std::forward<Func>(func));
|
||||
if constexpr (detail::isImmediateFuture<FuncRetType>::value) {
|
||||
return std::move(semiFut).deferValue(
|
||||
|
@ -48,6 +48,11 @@ struct continuation_result_impl<
|
||||
using type = typename T::element_type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct continuation_result_impl<void> {
|
||||
using type = folly::Unit;
|
||||
};
|
||||
|
||||
template <
|
||||
typename Func,
|
||||
typename Arg,
|
||||
|
@ -121,6 +121,9 @@ ImmediateFuture<folly::Unit> unitFunc() {
|
||||
TEST(ImmediateFuture, unit) {
|
||||
auto fut = unitFunc();
|
||||
EXPECT_TRUE(fut.hasImmediate());
|
||||
|
||||
auto voidFut = std::move(fut).thenValue([](folly::Unit) {});
|
||||
EXPECT_TRUE(voidFut.hasImmediate());
|
||||
}
|
||||
|
||||
class Foo {
|
||||
|
Loading…
Reference in New Issue
Block a user