-
Notifications
You must be signed in to change notification settings - Fork 82
Description
This is a strange, because it seems to compile and work fine on GCC and clang, but on MSVC (17.12.3) it fails to compile. Even on MSVC, it does work as expected, when you use lexy "normally", at runtime. The compilation error only happens when trying to use static_assert to check productions in constexpr at compile time. And even so, the static assert testing works as expected for the WithData class, just not the NoData class (that gets lexy::constructed without arguments). It seems to be related to the attempt to construct the class using lazy_init, but there are no args to forward.
Here is an example -- as I say, these "productions" build and parse fine at runtime, but when I use static_assert to check it at compile time as shown at the bottom of the code example, it fails to compile. It also fails if I just have the test() function return a bool true, so I don't think it's to do with the string_view...
namespace test {
struct NoData {
constexpr std::string_view test() const {
return "NoData";
}
};
struct WithData {
constexpr auto test() const {
return str;
}
std::string_view str;
};
static constexpr auto ident = dsl::identifier(dsl::ascii::alpha, dsl::ascii::alpha_digit_underscore);
static constexpr auto ws1 = dsl::while_one(dsl::ascii::space);
struct argument {
struct invalid {
static constexpr auto name = "invalid argument character";
};
static constexpr auto rule = ident;
static constexpr auto value = lexy::as_string<std::string_view>;
};
struct cmd_NoData {
static constexpr auto rule = LEXY_KEYWORD("NoData", ident) + dsl::eof;
static constexpr auto value = lexy::construct<NoData>;
};
struct cmd_WithData {
static constexpr auto rule = LEXY_KEYWORD("WithData", ident) >> ws1
+ dsl::p<argument> + dsl::eof;
static constexpr auto value = lexy::construct<WithData>;
};
static_assert([] {
constexpr auto result = lexy::parse<cmd_WithData>(lexy::zstring_input("WithData hello"), lexy::noop);
return result.has_value() && result.value().test() == "hello";
}());
static_assert([] {
constexpr auto result = lexy::parse<cmd_NoData>(lexy::zstring_input("NoData"), lexy::noop); // <-- this is line 89
return result.has_value() && result.value().test() == "NoData";
}());
} // namespace testThe compile errors start with:
C:\Users\...\src\test_Parser.cpp(89): error C2131: expression did not evaluate to a constant
C:\Users\...\out\build\x64-debug\vcpkg_installed\x64-windows\include\lexy/_detail/lazy_init.hpp(110): note: failure was caused by a read of an uninitialized symbol
C:\Users\...\out\build\x64-debug\vcpkg_installed\x64-windows\include\lexy/_detail/lazy_init.hpp(110): note: see usage of 'lexy::_detail::_lazy_init_storage_trivial<T>::_value'
with
[
T=test::NoData
]
C:\Users\...\src\test_Parser.inl(89): note: the call stack of the evaluation (the oldest call first) is
C:\Users\...\src\test_Parser.inl(89): note: while evaluating function 'lexy::parse_result<lexy::do_action::value_type,ErrorCallback> lexy::parse<test::cmd_NoData,lexy::string_input<lexy::default_encoding>,lexy::_noop>(const Input &,const ErrorCallback &)'
with
[
ErrorCallback=lexy::_noop,
Input=lexy::string_input<lexy::default_encoding>
]
C:\Users\...\out\build\x64-debug\vcpkg_installed\x64-windows\include\lexy/action/parse.hpp(173): note: while evaluating function 'lexy::parse_result<lexy::do_action::value_type,ErrorCallback> lexy::parse_action<void,lexy::string_input<lexy::default_encoding>,ErrorCallback>::operator ()<test::cmd_NoData>(Production,const Input &) const'
with
[
ErrorCallback=lexy::_noop,
Production=test::cmd_NoData,
Input=lexy::string_input<lexy::default_encoding>
]
P.S. Even stranger, the IntelliSense "squiggles" that show (red underlines) indicating an error are not present. If you modify the string input so it's invalid, you do get those static_assert red squiggly line appearing. As soon as you change it to "NoData", which should parse, the squiggles go away, so this "pre-compiler" seems to think it's error-free. But then when you actually build the file/project, you get the above errors... Again, if I comment out this static_assert and just use the lexy parser at runtime, everything seems to work fine, and I get the expected return value from the test() method on NoData.