Commit c3d3034c authored by Harris Hancock's avatar Harris Hancock Committed by Kenton Varda

Work around another Sequence_ member function-related bug in MSVC

The fix in ae6b4452 worked for getting the HTTP code building, but was
apparently insufficient for the capnp command line tools.
parent 4c169a09
...@@ -298,29 +298,46 @@ public: ...@@ -298,29 +298,46 @@ public:
explicit constexpr Sequence_(T&& firstSubParser, U&&... rest) explicit constexpr Sequence_(T&& firstSubParser, U&&... rest)
: first(kj::fwd<T>(firstSubParser)), rest(kj::fwd<U>(rest)...) {} : first(kj::fwd<T>(firstSubParser)), rest(kj::fwd<U>(rest)...) {}
// TODO(msvc): MSVC ICEs on the return types of operator() and parseNext() unless SubParsers is // TODO(msvc): The trailing return types on `operator()` and `parseNext()` expose at least two
// wrapped in `decltype(instance<SubParsers>())`. This is similar to the workaround in // bugs in MSVC:
// KJ_CONTEXT(). //
// 1. An ICE.
// 2. 'error C2672: 'operator __surrogate_func': no matching overloaded function found)',
// which crops up in numerous places when trying to build the capnp command line tools.
//
// The only workaround I found for both bugs is to omit the trailing return types and instead
// rely on C++14's return type deduction.
template <typename Input> template <typename Input>
auto operator()(Input& input) const -> auto operator()(Input& input) const
Maybe<decltype(tuple( #ifndef _MSC_VER
-> Maybe<decltype(tuple(
instance<OutputType<FirstSubParser, Input>>(), instance<OutputType<FirstSubParser, Input>>(),
instance<OutputType<decltype(instance<SubParsers>()), Input>>()...))> { instance<OutputType<SubParsers, Input>>()...))>
#endif
{
return parseNext(input); return parseNext(input);
} }
template <typename Input, typename... InitialParams> template <typename Input, typename... InitialParams>
auto parseNext(Input& input, InitialParams&&... initialParams) const -> auto parseNext(Input& input, InitialParams&&... initialParams) const
Maybe<decltype(tuple( #ifndef _MSC_VER
-> Maybe<decltype(tuple(
kj::fwd<InitialParams>(initialParams)..., kj::fwd<InitialParams>(initialParams)...,
instance<OutputType<FirstSubParser, Input>>(), instance<OutputType<FirstSubParser, Input>>(),
instance<OutputType<decltype(instance<SubParsers>()), Input>>()...))> { instance<OutputType<SubParsers, Input>>()...))>
#endif
{
KJ_IF_MAYBE(firstResult, first(input)) { KJ_IF_MAYBE(firstResult, first(input)) {
return rest.parseNext(input, kj::fwd<InitialParams>(initialParams)..., return rest.parseNext(input, kj::fwd<InitialParams>(initialParams)...,
kj::mv(*firstResult)); kj::mv(*firstResult));
} else { } else {
return nullptr; // TODO(msvc): MSVC depends on return type deduction to compile this function, so we need to
// help it deduce the right type on this code path.
return Maybe<decltype(tuple(
kj::fwd<InitialParams>(initialParams)...,
instance<OutputType<FirstSubParser, Input>>(),
instance<OutputType<SubParsers, Input>>()...))>{nullptr};
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment