Workaround for internal compiler error with msvc 16.7.x patch from https://github.com/capnproto/capnproto/pull/1058 --- a/c++/src/kj/one-of.h +++ b/c++/src/kj/one-of.h @@ -347,11 +347,23 @@ void OneOf::allHandled() { auto _kj_switch_subject = (value)._switchSubject(); \ switch (_kj_switch_subject->which()) #endif +#if !_MSC_VER || defined(__clang__) #define KJ_CASE_ONEOF(name, ...) \ break; \ case ::kj::Decay::template tagFor<__VA_ARGS__>(): \ for (auto& name = _kj_switch_subject->template get<__VA_ARGS__>(), *_kj_switch_done = &name; \ _kj_switch_done; _kj_switch_done = nullptr) +#else +// TODO(msvc): The latest MSVC which ships with VS2019 now ICEs on the implementation above. It +// appears we can hack around the problem by moving the `->template get<>()` syntax to an outer +// `if`. (This unfortunately allows wonky syntax like `KJ_CASE_ONEOF(a, B) { } else { }`.) +// https://developercommunity.visualstudio.com/content/problem/1143733/internal-compiler-error-on-v1670.html +#define KJ_CASE_ONEOF(name, ...) \ + break; \ + case ::kj::Decay::template tagFor<__VA_ARGS__>(): \ + if (auto* _kj_switch_done = &_kj_switch_subject->template get<__VA_ARGS__>()) \ + for (auto& name = *_kj_switch_done; _kj_switch_done; _kj_switch_done = nullptr) +#endif #define KJ_CASE_ONEOF_DEFAULT break; default: // Allows switching over a OneOf. //