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<Variants...>::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<decltype(*_kj_switch_subject)>::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<decltype(*_kj_switch_subject)>::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.
 //
