cppfront
cppfront copied to clipboard
[BUG] `@enum` value can't be interpolated
trafficstars
Title: @enum value can't be interpolated.
Minimal reproducer (https://cpp2.godbolt.org/z/bc16anzhP):
command: @enum type = {
count;
filter;
}
main: () = {
_ = "(command::count)$";
}
Commands:
cppfront main.cpp2
clang++18 -std=c++23 -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -Werror=unused-result -Werror=unused-value -Werror=unused-parameter -I . main.cpp
Expected result: Interpolation to use the generated to_string member function.
Actual result and error:
main.cpp2:6:37: error: cannot pass object of non-trivial type 'const command' through variadic function; call will abort at runtime [-Wnon-pod-varargs]
6 | static_cast<void>(cpp2::to_string(command::count));
| ^
1 error generated.
Cpp2 lowered to Cpp1:
//=== Cpp2 type declarations ====================================================
#include "cpp2util.h"
#line 1 "/app/example.cpp2"
class command;
#line 2 "/app/example.cpp2"
//=== Cpp2 type definitions and function declarations ===========================
#line 1 "/app/example.cpp2"
class command {
private: cpp2::i8 _value; private: constexpr command(cpp2::in<cpp2::i64> _val);
private: constexpr auto operator=(cpp2::in<cpp2::i64> _val) -> command& ;
public: [[nodiscard]] constexpr auto get_raw_value() const& -> cpp2::i8;
public: constexpr command(command const& that);
public: constexpr auto operator=(command const& that) -> command& ;
public: constexpr command(command&& that) noexcept;
public: constexpr auto operator=(command&& that) noexcept -> command& ;
public: [[nodiscard]] auto operator<=>(command const& that) const& -> std::strong_ordering = default;
public: static const command count;
public: static const command filter;
public: [[nodiscard]] auto to_string() const& -> std::string;
#line 4 "/app/example.cpp2"
};
auto main() -> int;
//=== Cpp2 function definitions =================================================
#line 1 "/app/example.cpp2"
#line 1 "/app/example.cpp2"
constexpr command::command(cpp2::in<cpp2::i64> _val)
: _value{ cpp2::unsafe_narrow<cpp2::i8>(_val) } { }
constexpr auto command::operator=(cpp2::in<cpp2::i64> _val) -> command& {
_value = cpp2::unsafe_narrow<cpp2::i8>(_val);
return *this; }
[[nodiscard]] constexpr auto command::get_raw_value() const& -> cpp2::i8 { return _value; }
constexpr command::command(command const& that)
: _value{ that._value }{}
constexpr auto command::operator=(command const& that) -> command& {
_value = that._value;
return *this;}
constexpr command::command(command&& that) noexcept
: _value{ std::move(that)._value }{}
constexpr auto command::operator=(command&& that) noexcept -> command& {
_value = std::move(that)._value;
return *this;}
inline CPP2_CONSTEXPR command command::count = 0;
inline CPP2_CONSTEXPR command command::filter = 1;
[[nodiscard]] auto command::to_string() const& -> std::string{
if ((*this) == count) {return "count"; }
if ((*this) == filter) {return "filter"; }
return "invalid command value";
}
#line 5 "/app/example.cpp2"
auto main() -> int{
static_cast<void>(cpp2::to_string(command::count));
}
There is a way to make @enum able to be interpolated (https://cpp2.godbolt.org/z/xa8oo74qK):
command: @enum type = {
count;
filter;
}
template<> struct std::formatter<command> : formatter<string> {
auto format(command c, auto&& ctx) const {
return formatter<string>::format(c.to_string(), CPP2_FORWARD(ctx));
}
};
main: () = {
std::cout << "(command::count:)$\n";
}
But you need contextual knowledge to add the : to the string.