cppfront icon indicating copy to clipboard operation
cppfront copied to clipboard

[BUG] `@enum` value can't be interpolated

Open JohelEGP opened this issue 1 year ago • 1 comments
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));
}

JohelEGP avatar Dec 05 '23 04:12 JohelEGP

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.

JohelEGP avatar Dec 09 '23 18:12 JohelEGP