Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Few issues with fallback_formatter #1647

Closed
sitano opened this issue Apr 23, 2020 · 1 comment
Closed

Few issues with fallback_formatter #1647

sitano opened this issue Apr 23, 2020 · 1 comment

Comments

@sitano
Copy link

sitano commented Apr 23, 2020

seastar does not compile with 6.2.0-1 fmt on my machine.

I have reproduced the errors with the following code:

#include <fmt/core.h>
#include <fmt/format.h>
#include <fmt/printf.h>
#include <sstream>
#include <iostream>

namespace db {
  enum class consistency_level {};

  std::ostream& operator<<(std::ostream& os, consistency_level cl);
}

std::string unavailable_exception(db::consistency_level cl) {
  return fmt::sprintf("%s", cl);
}


int main() {
  std::cout << unavailable_exception(does_not_matter);
}

Output:

In file included from 1.cc:2:
/usr/include/fmt/format.h: In instantiation of ‘decltype (ctx.out()) fmt::v6::formatter<T, Char, typename std::enable_if<(fmt::v6::internal::type_constant<T, Char>::value != fmt::v6::internal::type::custom_type), void>::type>::format(const T&, FormatContext&) [with FormatContext = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; T = fmt::v6::basic_string_view<char>; Char = char; typename std::enable_if<(fmt::v6::internal::type_constant<T, Char>::value != fmt::v6::internal::type::custom_type), void>::type = void; decltype (ctx.out()) = std::back_insert_iterator<fmt::v6::internal::buffer<char> >]’:
/usr/include/fmt/ostream.h:113:60:   required from ‘decltype (ctx.out()) fmt::v6::internal::fallback_formatter<T, Char, typename std::enable_if<fmt::v6::internal::is_streamable<T, Char>::value, void>::type>::format(const T&, Context&) [with Context = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; T = db::consistency_level; Char = char; typename std::enable_if<fmt::v6::internal::is_streamable<T, Char>::value, void>::type = void; decltype (ctx.out()) = std::back_insert_iterator<fmt::v6::internal::buffer<char> >]’
/usr/include/fmt/core.h:898:5:   required from ‘static void fmt::v6::internal::value<Context>::format_custom_arg(const void*, fmt::v6::basic_format_parse_context<typename Context::char_type>&, Context&) [with T = db::consistency_level; Formatter = fmt::v6::internal::fallback_formatter<db::consistency_level, char, void>; Context = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; typename Context::char_type = char]’
/usr/include/fmt/core.h:882:19:   required from ‘fmt::v6::internal::value<Context>::value(const T&) [with T = db::consistency_level; Context = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>]’
/usr/include/fmt/core.h:1213:39:   required from ‘fmt::v6::internal::value<Context> fmt::v6::internal::make_arg(const T&) [with bool IS_PACKED = true; Context = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; T = db::consistency_level; typename std::enable_if<IS_PACKED, int>::type <anonymous> = 0]’
/usr/include/fmt/core.h:1349:53:   required from ‘fmt::v6::format_arg_store<Context, Args>::format_arg_store(const Args& ...) [with Context = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; Args = {db::consistency_level}]’
/usr/include/fmt/core.h:1364:18:   required from ‘fmt::v6::format_arg_store<Context, Args ...> fmt::v6::make_format_args(const Args& ...) [with Context = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; Args = {db::consistency_level}]’
/usr/include/fmt/printf.h:627:68:   required from ‘std::__cxx11::basic_string<Char> fmt::v6::sprintf(const S&, const Args& ...) [with S = char [3]; Args = {db::consistency_level}; Char = char]’
1.cc:14:31:   required from here
/usr/include/fmt/format.h:3012:29: error: no matching function for call to ‘fmt::v6::arg_formatter<fmt::v6::internal::output_range<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char> >::arg_formatter(fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>&, std::nullptr_t, fmt::v6::internal::dynamic_format_specs<char>*)’
 3012 |     return visit_format_arg(arg_formatter<range_type>(ctx, nullptr, &specs_),
      |                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/fmt/format.h:2764:12: note: candidate: ‘fmt::v6::arg_formatter<Range>::arg_formatter(fmt::v6::arg_formatter<Range>::context_type&, fmt::v6::basic_format_parse_context<typename Range::value_type>*, fmt::v6::arg_formatter<Range>::format_specs*) [with Range = fmt::v6::internal::output_range<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; fmt::v6::arg_formatter<Range>::context_type = fmt::v6::basic_format_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; typename Range::value_type = char; typename fmt::v6::internal::arg_formatter_base<Range>::iterator = std::back_insert_iterator<fmt::v6::internal::buffer<char> >; fmt::v6::arg_formatter<Range>::format_specs = fmt::v6::basic_format_specs<char>]’
 2764 |   explicit arg_formatter(
      |            ^~~~~~~~~~~~~
/usr/include/fmt/format.h:2765:21: note:   no known conversion for argument 1 from ‘fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>’ to ‘fmt::v6::arg_formatter<fmt::v6::internal::output_range<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char> >::context_type&’ {aka ‘fmt::v6::basic_format_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>&’}
 2765 |       context_type& ctx,
      |       ~~~~~~~~~~~~~~^~~
/usr/include/fmt/format.h:2743:7: note: candidate: ‘constexpr fmt::v6::arg_formatter<fmt::v6::internal::output_range<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char> >::arg_formatter(const fmt::v6::arg_formatter<fmt::v6::internal::output_range<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char> >&)’
 2743 | class arg_formatter : public internal::arg_formatter_base<Range> {
      |       ^~~~~~~~~~~~~
/usr/include/fmt/format.h:2743:7: note:   candidate expects 1 argument, 3 provided
/usr/include/fmt/format.h:2743:7: note: candidate: ‘constexpr fmt::v6::arg_formatter<fmt::v6::internal::output_range<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char> >::arg_formatter(fmt::v6::arg_formatter<fmt::v6::internal::output_range<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char> >&&)’
/usr/include/fmt/format.h:2743:7: note:   candidate expects 1 argument, 3 provided
/usr/include/fmt/format.h: In instantiation of ‘void fmt::v6::internal::handle_dynamic_spec(int&, fmt::v6::internal::arg_ref<typename Context::char_type>, Context&) [with Handler = fmt::v6::internal::width_checker; Context = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; typename Context::char_type = char]’:
/usr/include/fmt/format.h:3005:59:   required from ‘decltype (ctx.out()) fmt::v6::formatter<T, Char, typename std::enable_if<(fmt::v6::internal::type_constant<T, Char>::value != fmt::v6::internal::type::custom_type), void>::type>::format(const T&, FormatContext&) [with FormatContext = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; T = fmt::v6::basic_string_view<char>; Char = char; typename std::enable_if<(fmt::v6::internal::type_constant<T, Char>::value != fmt::v6::internal::type::custom_type), void>::type = void; decltype (ctx.out()) = std::back_insert_iterator<fmt::v6::internal::buffer<char> >]’
/usr/include/fmt/ostream.h:113:60:   required from ‘decltype (ctx.out()) fmt::v6::internal::fallback_formatter<T, Char, typename std::enable_if<fmt::v6::internal::is_streamable<T, Char>::value, void>::type>::format(const T&, Context&) [with Context = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; T = db::consistency_level; Char = char; typename std::enable_if<fmt::v6::internal::is_streamable<T, Char>::value, void>::type = void; decltype (ctx.out()) = std::back_insert_iterator<fmt::v6::internal::buffer<char> >]’
/usr/include/fmt/core.h:898:5:   required from ‘static void fmt::v6::internal::value<Context>::format_custom_arg(const void*, fmt::v6::basic_format_parse_context<typename Context::char_type>&, Context&) [with T = db::consistency_level; Formatter = fmt::v6::internal::fallback_formatter<db::consistency_level, char, void>; Context = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; typename Context::char_type = char]’
/usr/include/fmt/core.h:882:19:   required from ‘fmt::v6::internal::value<Context>::value(const T&) [with T = db::consistency_level; Context = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>]’
/usr/include/fmt/core.h:1213:39:   required from ‘fmt::v6::internal::value<Context> fmt::v6::internal::make_arg(const T&) [with bool IS_PACKED = true; Context = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; T = db::consistency_level; typename std::enable_if<IS_PACKED, int>::type <anonymous> = 0]’
/usr/include/fmt/core.h:1349:53:   required from ‘fmt::v6::format_arg_store<Context, Args>::format_arg_store(const Args& ...) [with Context = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; Args = {db::consistency_level}]’
/usr/include/fmt/core.h:1364:18:   required from ‘fmt::v6::format_arg_store<Context, Args ...> fmt::v6::make_format_args(const Args& ...) [with Context = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; Args = {db::consistency_level}]’
/usr/include/fmt/printf.h:627:68:   required from ‘std::__cxx11::basic_string<Char> fmt::v6::sprintf(const S&, const Args& ...) [with S = char [3]; Args = {db::consistency_level}; Char = char]’
1.cc:14:31:   required from here
/usr/include/fmt/format.h:2717:53: error: ‘class fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>’ has no member named ‘error_handler’
 2717 |                                                 ctx.error_handler());
      |                                                 ~~~~^~~~~~~~~~~~~
/usr/include/fmt/format.h:2720:65: error: cannot convert ‘fmt::v6::basic_string_view<char>’ to ‘int’
 2720 |     value = internal::get_dynamic_spec<Handler>(ctx.arg(ref.val.name),
      |                                                         ~~~~~~~~^~~~
      |                                                                 |
      |                                                                 fmt::v6::basic_string_view<char>
In file included from 1.cc:3:
/usr/include/fmt/printf.h:363:22: note:   initializing argument 1 of ‘fmt::v6::basic_printf_context<OutputIt, Char>::format_arg fmt::v6::basic_printf_context<OutputIt, Char>::arg(int) const [with OutputIt = std::back_insert_iterator<fmt::v6::internal::buffer<char> >; Char = char; fmt::v6::basic_printf_context<OutputIt, Char>::format_arg = fmt::v6::basic_format_arg<fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char> >]’
  363 |   format_arg arg(int id) const { return args_.get(id); }
      |                  ~~~~^~
In file included from 1.cc:2:
/usr/include/fmt/format.h:2721:53: error: ‘class fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>’ has no member named ‘error_handler’
 2721 |                                                 ctx.error_handler());
      |                                                 ~~~~^~~~~~~~~~~~~
/usr/include/fmt/format.h: In instantiation of ‘void fmt::v6::internal::handle_dynamic_spec(int&, fmt::v6::internal::arg_ref<typename Context::char_type>, Context&) [with Handler = fmt::v6::internal::precision_checker; Context = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; typename Context::char_type = char]’:
/usr/include/fmt/format.h:3007:63:   required from ‘decltype (ctx.out()) fmt::v6::formatter<T, Char, typename std::enable_if<(fmt::v6::internal::type_constant<T, Char>::value != fmt::v6::internal::type::custom_type), void>::type>::format(const T&, FormatContext&) [with FormatContext = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; T = fmt::v6::basic_string_view<char>; Char = char; typename std::enable_if<(fmt::v6::internal::type_constant<T, Char>::value != fmt::v6::internal::type::custom_type), void>::type = void; decltype (ctx.out()) = std::back_insert_iterator<fmt::v6::internal::buffer<char> >]’
/usr/include/fmt/ostream.h:113:60:   required from ‘decltype (ctx.out()) fmt::v6::internal::fallback_formatter<T, Char, typename std::enable_if<fmt::v6::internal::is_streamable<T, Char>::value, void>::type>::format(const T&, Context&) [with Context = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; T = db::consistency_level; Char = char; typename std::enable_if<fmt::v6::internal::is_streamable<T, Char>::value, void>::type = void; decltype (ctx.out()) = std::back_insert_iterator<fmt::v6::internal::buffer<char> >]’
/usr/include/fmt/core.h:898:5:   required from ‘static void fmt::v6::internal::value<Context>::format_custom_arg(const void*, fmt::v6::basic_format_parse_context<typename Context::char_type>&, Context&) [with T = db::consistency_level; Formatter = fmt::v6::internal::fallback_formatter<db::consistency_level, char, void>; Context = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; typename Context::char_type = char]’
/usr/include/fmt/core.h:882:19:   required from ‘fmt::v6::internal::value<Context>::value(const T&) [with T = db::consistency_level; Context = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>]’
/usr/include/fmt/core.h:1213:39:   required from ‘fmt::v6::internal::value<Context> fmt::v6::internal::make_arg(const T&) [with bool IS_PACKED = true; Context = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; T = db::consistency_level; typename std::enable_if<IS_PACKED, int>::type <anonymous> = 0]’
/usr/include/fmt/core.h:1349:53:   required from ‘fmt::v6::format_arg_store<Context, Args>::format_arg_store(const Args& ...) [with Context = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; Args = {db::consistency_level}]’
/usr/include/fmt/core.h:1364:18:   required from ‘fmt::v6::format_arg_store<Context, Args ...> fmt::v6::make_format_args(const Args& ...) [with Context = fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>; Args = {db::consistency_level}]’
/usr/include/fmt/printf.h:627:68:   required from ‘std::__cxx11::basic_string<Char> fmt::v6::sprintf(const S&, const Args& ...) [with S = char [3]; Args = {db::consistency_level}; Char = char]’
1.cc:14:31:   required from here
/usr/include/fmt/format.h:2717:53: error: ‘class fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>’ has no member named ‘error_handler’
 2717 |                                                 ctx.error_handler());
      |                                                 ~~~~^~~~~~~~~~~~~
/usr/include/fmt/format.h:2720:65: error: cannot convert ‘fmt::v6::basic_string_view<char>’ to ‘int’
 2720 |     value = internal::get_dynamic_spec<Handler>(ctx.arg(ref.val.name),
      |                                                         ~~~~~~~~^~~~
      |                                                                 |
      |                                                                 fmt::v6::basic_string_view<char>
In file included from 1.cc:3:
/usr/include/fmt/printf.h:363:22: note:   initializing argument 1 of ‘fmt::v6::basic_printf_context<OutputIt, Char>::format_arg fmt::v6::basic_printf_context<OutputIt, Char>::arg(int) const [with OutputIt = std::back_insert_iterator<fmt::v6::internal::buffer<char> >; Char = char; fmt::v6::basic_printf_context<OutputIt, Char>::format_arg = fmt::v6::basic_format_arg<fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char> >]’
  363 |   format_arg arg(int id) const { return args_.get(id); }
      |                  ~~~~^~
In file included from 1.cc:2:
/usr/include/fmt/format.h:2721:53: error: ‘class fmt::v6::basic_printf_context<std::back_insert_iterator<fmt::v6::internal::buffer<char> >, char>’ has no member named ‘error_handler’
 2721 |                                                 ctx.error_handler());

Indeed:

  • basic_printf_context does not have an error_handler()
  • arg(fmt::v6::basic_string_view<char>) does not exists in basic_printf_context
  • arg_formatter can't explicitly cast wrong super type
@vitaut
Copy link
Contributor

vitaut commented Apr 23, 2020

This has been fixed in master already (#1631): https://godbolt.org/z/br6fvT

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants