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:
explicit constexpr Sequence_(T&& firstSubParser, 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
// wrapped in `decltype(instance<SubParsers>())`. This is similar to the workaround in
// KJ_CONTEXT().
// TODO(msvc): The trailing return types on `operator()` and `parseNext()` expose at least two
// bugs in MSVC:
//
// 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>
auto operator()(Input& input) const ->
Maybe<decltype(tuple(
auto operator()(Input& input) const
#ifndef _MSC_VER
-> Maybe<decltype(tuple(
instance<OutputType<FirstSubParser, Input>>(),
instance<OutputType<decltype(instance<SubParsers>()), Input>>()...))> {
instance<OutputType<SubParsers, Input>>()...))>
#endif
{
return parseNext(input);
}
template <typename Input, typename... InitialParams>
auto parseNext(Input& input, InitialParams&&... initialParams) const ->
Maybe<decltype(tuple(
auto parseNext(Input& input, InitialParams&&... initialParams) const
#ifndef _MSC_VER
-> Maybe<decltype(tuple(
kj::fwd<InitialParams>(initialParams)...,
instance<OutputType<FirstSubParser, Input>>(),
instance<OutputType<decltype(instance<SubParsers>()), Input>>()...))> {
instance<OutputType<SubParsers, Input>>()...))>
#endif
{
KJ_IF_MAYBE(firstResult, first(input)) {
return rest.parseNext(input, kj::fwd<InitialParams>(initialParams)...,
kj::mv(*firstResult));
} 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