glaze icon indicating copy to clipboard operation
glaze copied to clipboard

JSON Schema broken with MSVC since v5.0.0

Open dbraeckelmann opened this issue 9 months ago • 4 comments

JSON schema does not work in glaze > v4.4.3 with MSVC 17.13 / 17.14 preview anymore; works with GCC though.

This minimal example compiles and works fine with v4.4.3 but results in a compilation error starting with v5.0.0:

#include "glaze/glaze.hpp"

#include <string>
#include <print>

struct local_schema_t
{
   int x{};

   struct glaze_json_schema
   {
      glz::schema x{.description = "x is a special integer", .minimum = 1};
   };
};

int main() {
    local_schema_t t {};
    std::println("{}", glz::write_json_schema<local_schema_t>().value());
}

Full error message:

C:\glaze_test\build\_deps\glaze-src\include\glaze\core\opts.hpp(369,61): error C2131: expression did not evaluate to a constant [C:\glaze_test\build\GlazeTest.vcxproj]
  (compiling source file '../main.cpp')
      C:\glaze_test\build\_deps\glaze-src\include\glaze\core\opts.hpp(364,10):
      a non-constant (sub-)expression was encountered
      C:\glaze_test\build\_deps\glaze-src\include\glaze\core\opts.hpp(369,61):
      the call stack of the evaluation (the oldest call first) is
          C:\glaze_test\build\_deps\glaze-src\include\glaze\core\opts.hpp(369,37):
          while evaluating function 'glz::write_json_schema::opts_write_type_info_off glz::opt_on<glz::write_json_schema::opts_write_type_info_off{glz::opts{uint32_t:10,bool:true,bool:false,bool:true,bool:true,bool:true,bool:false,bool:false,char:32,uint8_t:3,bool:true,bool:false,bool:false,bool:false,uint8_t:0,glz::float_precision:glz::float_precision::full,bool:false,bool:false,bool:false,bool:false,bool:false,bool:false,bool:false,uint32_t:0},bool:false},&glz::opts::raw>(void)'
      C:\glaze_test\build\_deps\glaze-src\include\glaze\core\opts.hpp(369,61):
      the template instantiation context (the oldest one first) is
          C:\glaze_test\main.cpp(19,29):
          see reference to function template instantiation 'std::expected<std::string,glz::error_ctx> glz::write_json_schema<local_schema_t,glz::opts{uint32_t:10,bool:true,bool:false,bool:true,bool:true,bool:true,bool:false,bool:false,char:32,uint8_t:3,bool:true,bool:false,bool:false,bool:false,uint8_t:0,glz::float_precision:glz::float_precision::full,bool:false,bool:false,bool:false,bool:false,bool:false,bool:false,bool:false,uint32_t:0}>(void)' being compiled
          C:\glaze_test\build\_deps\glaze-src\include\glaze\json\schema.hpp(686,28):
          see reference to function template instantiation 'glz::error_ctx glz::write_json_schema<local_schema_t,glz::opts{uint32_t:10,bool:true,bool:false,bool:true,bool:true,bool:true,bool:false,bool:false,char:32,uint8_t:3,bool:true,bool:false,bool:false,bool:false,uint8_t:0,glz::float_precision:glz::float_precision::full,bool:false,bool:false,bool:false,bool:false,bool:false,bool:false,bool:false,uint32_t:0},std::string&>(Buffer)' being compiled
          with
          [
              Buffer=std::string &
          ]
          C:\glaze_test\build\_deps\glaze-src\include\glaze\json\schema.hpp(679,14):
          see reference to function template instantiation 'glz::error_ctx glz::write<glz::write_json_schema::opts_write_type_info_off{glz::opts{uint32_t:10,bool:true,bool:false,bool:true,bool:true,bool:true,bool:false,bool:false,char:32,uint8_t:3,bool:true,bool:false,bool:false,bool:false,uint8_t:0,glz::float_precision:glz::float_precision::full,bool:false,bool:false,bool:false,bool:false,bool:false,bool:false,bool:false,uint32_t:0},bool:false},glz::detail::schematic,std::string>(T &&,Buffer &)' being compiled
          with
          [
              T=glz::detail::schematic,
              Buffer=std::string
          ]
          C:\glaze_test\build\_deps\glaze-src\include\glaze\core\write.hpp(70,14):
          see reference to function template instantiation 'glz::error_ctx glz::write<glz::write_json_schema::opts_write_type_info_off{glz::opts{uint32_t:10,bool:true,bool:false,bool:true,bool:true,bool:true,bool:false,bool:false,char:32,uint8_t:3,bool:true,bool:false,bool:false,bool:false,uint8_t:0,glz::float_precision:glz::float_precision::full,bool:false,bool:false,bool:false,bool:false,bool:false,bool:false,bool:false,uint32_t:0},bool:false},_Ty,Buffer,glz::context&>(T &&,Buffer &,_T0)' being compiled
          with
          [
              _Ty=glz::detail::schematic,
              Buffer=std::string,
              T=glz::detail::schematic,
              _T0=glz::context &
          ]
          C:\glaze_test\build\_deps\glaze-src\include\glaze\core\write.hpp(25,57):
          see reference to function template instantiation 'void glz::to<10,glz::detail::schematic>::op<glz::write_json_schema::opts_write_type_info_off{glz::opts{uint32_t:10,bool:true,bool:false,bool:true,bool:true,bool:true,bool:false,bool:false,char:32,uint8_t:3,bool:true,bool:false,bool:false,bool:false,uint8_t:0,glz::float_precision:glz::float_precision::full,bool:false,bool:false,bool:false,bool:false,bool:false,bool:false,bool:false,uint32_t:0},bool:false},_Ty,Buffer&,glz::context&,size_t&>(V &&,_T0,B,_T1)' being compiled
          with
          [
              _Ty=glz::detail::schematic,
              Buffer=std::string,
              V=glz::detail::schematic,
              _T0=glz::context &,
              B=std::string &,
              _T1=size_t &
          ]
          C:\glaze_test\build\_deps\glaze-src\include\glaze\json\write.hpp(1791,16):
          see reference to function template instantiation 'void glz::invoke_table<34,glz::to<10,glz::detail::schematic>::op::<lambda_2>>(Lambda &&)' being compiled
          with
          [
              Lambda=glz::to<10,glz::detail::schematic>::op::<lambda_2>
          ]
          C:\glaze_test\build\_deps\glaze-src\include\glaze\util\for_each.hpp(247,7):
          see reference to function template instantiation 'void glz::to<10,glz::detail::schematic>::op::<lambda_2>::operator ()<6>(void) const' being compiled
          C:\glaze_test\build\_deps\glaze-src\include\glaze\json\write.hpp(1862,51):
          see reference to function template instantiation 'void glz::to<10,glz::to<10,glz::detail::schematic>::op::<lambda_2>::()::val_t>::op<glz::write_json_schema::opts_write_type_info_off{glz::opts{uint32_t:10,bool:true,bool:false,bool:true,bool:true,bool:true,bool:false,bool:false,char:32,uint8_t:3,bool:true,bool:false,bool:false,bool:false,uint8_t:0,glz::float_precision:glz::float_precision::full,bool:false,bool:false,bool:false,bool:false,bool:false,bool:false,bool:false,uint32_t:0},bool:false},glz::opts_wrapper_t<glz::opts_wrapper::<lambda_1>::()::V,&glz::opts::raw>,glz::context&,Buffer&,size_t&>(_T0 &&,_T1,Buffer &,size_t &)' being compiled
          with
          [
              Buffer=std::string,
              _T0=glz::opts_wrapper_t<glz::opts_wrapper::<lambda_1>::()::V,&glz::opts::raw>,
              _T1=glz::context &
          ]
          C:\glaze_test\build\_deps\glaze-src\include\glaze\json\wrappers.hpp(64,39):
          see reference to variable template 'const glz::write_json_schema::opts_write_type_info_off opt_true<`glz::write_json_schema<local_schema_t,glz::opts{unsigned int:10,bool:1,bool:0,bool:1,bool:1,bool:1,bool:0,bool:0,char:32,unsigned char:3,bool:1,bool:0,bool:0,bool:0,unsigned char:0,enum glz::float_precision:0,bool:0,bool:0,bool:0,bool:0,bool:0,bool:0,bool:0,unsigned int:0},std::basic_string<char,std::char_traits<char>,std::allocator<char> > &>'::`2'::opts_write_type_info_off{glz::opts{unsigned int:10,bool:1,bool:0,bool:1,bool:1,bool:1,bool:0,bool:0,char:32,unsigned char:3,bool:1,bool:0,bool:0,bool:0,unsigned char:0,enum glz::float_precision:0,bool:0,bool:0,bool:0,bool:0,bool:0,bool:0,bool:0,unsigned int:0},bool:0},22>' being compiled
  
C:\glaze_test\build\_deps\glaze-src\include\glaze\json\wrappers.hpp(64,36): error C2672: 'glz::to<10,glz::to<10,glz::detail::schematic>::op::<lambda_2>::()::val_t>::op': no matching overloaded function found [C:\glaze_test\build\GlazeTest.vcxproj]
  (compiling source file '../main.cpp')
      C:\glaze_test\build\_deps\glaze-src\include\glaze\json\write.hpp(1305,37):
      could be 'void glz::to<10,glz::to<10,glz::detail::schematic>::op::<lambda_2>::()::val_t>::op(_T0 &&,_T1 &&,_T2 &&,_T3 &&)'
          C:\glaze_test\build\_deps\glaze-src\include\glaze\json\wrappers.hpp(64,39):
          expression did not evaluate to a constant
              C:\glaze_test\build\_deps\glaze-src\include\glaze\core\opts.hpp(364,10):
              a non-constant (sub-)expression was encountered
  

dbraeckelmann avatar Apr 09 '25 06:04 dbraeckelmann

The msvc github action shows the same problem.

dbraeckelmann avatar Apr 09 '25 06:04 dbraeckelmann

Thanks for reporting this, I just discovered this a couple days ago as well. MSVC GitHub actions were broken for a while due to a compiler regression bug, but now I can thankfully run MSVC actions again.

I'll try to fix this ASAP. I'm hoping I'm able to find a work around and don't need to wait for another MSVC bug fix.

stephenberry avatar Apr 09 '25 11:04 stephenberry

Thanks, Stephen! It's not really a hurry for us, I just noticed this when trying to upgrade from v4.4.3 to v5.0.0 the other day.

dbraeckelmann avatar Apr 09 '25 11:04 dbraeckelmann

I was able to distill the problem down and submitted an MSVC bug report.

Hopefully it will be fixed soon, as it is needed for the configurable option handling in Glaze v5.

stephenberry avatar Apr 09 '25 12:04 stephenberry

Issue is fixed with MSVC 17.14 released yesterday.

dbraeckelmann avatar May 14 '25 07:05 dbraeckelmann

Yay!

stephenberry avatar May 14 '25 14:05 stephenberry