Skip to content

Commit

Permalink
sstring: prevent fmt from formatting sstring as a sequence
Browse files Browse the repository at this point in the history
since fmt 11, if fmt/ranges.h is included, it tries to format
a sequence-like container as a sequence. this confuses the compiler,
and prevents fmt from considering sstring a formattable, as
this type now has two formatters:

- one is the specialization of fmt::formatter provided by
  sstring.hh
- another is the one provided by fmt/ranges.h

that's why we started to have following build failure:

```
/home/kefu/.local/bin/clang++ -DFMT_SHARED -DSEASTAR_API_LEVEL=7 -DSEASTAR_BUILD_SHARED_LIBS -DSEASTAR_DEBUG -DSEASTAR_DEBUG_PROMISE -DSEASTAR_DEBUG_SHARED_PTR -DSEASTAR_DEFAULT_ALLOCATOR -DSEASTAR_DEFERRED_ACTION_REQUIRE_NOEXCEPT -DSEAST
AR_DEPRECATED_OSTREAM_FORMATTERS -DSEASTAR_HAS_MEMBARRIER -DSEASTAR_HAVE_ASAN_FIBER_SUPPORT -DSEASTAR_HAVE_HWLOC -DSEASTAR_HAVE_NUMA -DSEASTAR_HAVE_SYSTEMTAP_SDT -DSEASTAR_HAVE_URING -DSEASTAR_LOGGER_COMPILE_TIME_FMT -DSEASTAR_LOGGER_TYPE
_STDOUT -DSEASTAR_PTHREAD_ATTR_SETAFFINITY_NP -DSEASTAR_SCHEDULING_GROUPS_COUNT=16 -DSEASTAR_SHUFFLE_TASK_QUEUE -DSEASTAR_SSTRING -DSEASTAR_STRERROR_R_CHAR_P -DSEASTAR_THREAD_STACK_GUARDS -DSEASTAR_TYPE_ERASE_MORE -Dseastar_EXPORTS -I/hom
e/kefu/dev/seastar/include -I/home/kefu/dev/seastar/build/debug/gen/include -I/home/kefu/dev/seastar/build/debug/gen/src -I/home/kefu/dev/seastar/src -g -std=gnu++23 -fPIC -U_FORTIFY_SOURCE -Wno-error=unused-result "-Wno-error=#warnings"
-fstack-clash-protection -UNDEBUG -Wall -Werror -Wimplicit-fallthrough -Wdeprecated -Wno-error=deprecated -gz -fsanitize=address -fsanitize=undefined -fno-sanitize=vptr -MD -MT CMakeFiles/seastar.dir/src/core/execution_stage.cc.o -MF CMak
eFiles/seastar.dir/src/core/execution_stage.cc.o.d -o CMakeFiles/seastar.dir/src/core/execution_stage.cc.o -c /home/kefu/dev/seastar/src/core/execution_stage.cc
In file included from /home/kefu/dev/seastar/src/core/execution_stage.cc:28:
In file included from /home/kefu/dev/seastar/include/seastar/core/execution_stage.hh:24:
In file included from /home/kefu/dev/seastar/include/seastar/core/future.hh:28:
In file included from /usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/functional:49:
In file included from /usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/stl_function.h:60:
In file included from /usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/move.h:37:
/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/type_traits:1118:21: error: static assertion failed due to requirement 'std::__is_complete_or_unbounded(std::__type_identity<fmt::formatter<seastar::basic_sstring<char, unsign
ed int, 15, true>, char, void>>{})': template argument must be a complete class or an unbounded array
 1118 |       static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/fmt/base.h:1509:39: note: in instantiation of template class 'std::is_constructible<fmt::formatter<seastar::basic_sstring<char, unsigned int, 15>>>' requested here
 1509 |                                      (has_formatter<U, Context>::value &&
      |                                       ^
/usr/include/fmt/base.h:1516:40: note: in instantiation of template class 'fmt::detail::arg_mapper<fmt::context>::formattable<const seastar::basic_sstring<char, unsigned int, 15>>' requested here
 1516 |   template <typename T, FMT_ENABLE_IF(!formattable<T>::value)>
      |                                        ^
/usr/include/fmt/base.h:1517:20: note: while substituting prior template arguments into non-type template parameter [with T = const seastar::basic_sstring<char, unsigned int, 15>]
 1517 |   FMT_MAP_API auto do_map(T&) -> unformattable {
      |                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 1518 |     return {};
      |     ~~~~~~~~~~
 1519 |   }
      |   ~
/usr/include/fmt/base.h:1529:62: note: while substituting deduced template arguments into function template 'do_map' [with T = const seastar::basic_sstring<char, unsigned int, 15>, $1 = (no value)]
 1529 |   FMT_MAP_API auto map(T& val) -> decltype(FMT_DECLTYPE_THIS do_map(val)) {
      |                                                              ^
/usr/include/fmt/base.h:1545:50: note: while substituting deduced template arguments into function template 'map' [with T = const seastar::basic_sstring<char, unsigned int, 15>, U = (no value), $2 = (no value)]
 1545 |     type_constant<decltype(arg_mapper<Context>().map(std::declval<const T&>())),
      |                                                  ^
/usr/include/fmt/base.h:2718:16: note: in instantiation of template type alias 'mapped_type_constant' requested here
 2718 |       : types_{mapped_type_constant<Args, buffered_context<Char>>::value...},
      |                ^
/usr/include/fmt/base.h:2869:47: note: in instantiation of member function 'fmt::detail::format_string_checker<char, seastar::basic_sstring<char, unsigned int, 15>, seastar::basic_sstring<char, unsigned int, 15>>::format_string_checker' r
equested here
 2869 |       detail::parse_format_string<true>(str_, checker(s));
      |                                               ^
/home/kefu/dev/seastar/include/seastar/core/execution_stage.hh:342:33: note: in instantiation of function template specialization 'fmt::basic_format_string<char, seastar::basic_sstring<char, unsigned int, 15> &, const seastar::basic_sstri
ng<char, unsigned int, 15> &>::basic_format_string<char[6], 0>' requested here
  342 |         auto name = fmt::format("{}.{}", _name, sg.name());
      |                                 ^
```

in this change, we check for the FMT_VERSION, and explicitly
opt out of range-based formatter.

since fmt 11 was release only two weeks ago at the time of writing,
quite a few of existing user of fmt have not started using fmt 11,
we do not add this template specialization for fmt < 11, even if
this does not hurt, but it could slightly slow down the compilation
due to inclusion of fmt/ranges.h and processing the template.

Signed-off-by: Kefu Chai <[email protected]>
  • Loading branch information
tchaikov authored and avikivity committed Jul 17, 2024
1 parent bd27a45 commit b8fc54d
Showing 1 changed file with 11 additions and 0 deletions.
11 changes: 11 additions & 0 deletions include/seastar/core/sstring.hh
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
#include <functional>
#include <type_traits>
#include <fmt/format.h>
#if FMT_VERSION >= 110000
#include <fmt/ranges.h>
#endif
#endif
#include <seastar/util/std-compat.hh>
#include <seastar/util/modules.hh>
Expand Down Expand Up @@ -880,6 +883,14 @@ std::ostream& operator<<(std::ostream& os, const std::unordered_map<Key, T, Hash

#endif

#if FMT_VERSION >= 110000

template <typename char_type, typename Size, Size max_size, bool NulTerminate>
struct fmt::range_format_kind<seastar::basic_sstring<char_type, Size, max_size, NulTerminate>, char_type> : std::integral_constant<fmt::range_format, fmt::range_format::disabled>
{};

#endif

#if FMT_VERSION >= 90000

// Due to https://github.com/llvm/llvm-project/issues/68849, we inherit
Expand Down

0 comments on commit b8fc54d

Please sign in to comment.