-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Closed
Description
Hi, I'm currently testing whether I'd be able to use fmtlib as a module in my project, and upon trying the following code, I get a hefty compilation error:
import std;
import fmt;
int main() {
fmt::println("Test: {}", std::chrono::seconds(600));
}This is my CMakeLists.txt:
cmake_minimum_required(VERSION 4.1)
set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444")
project(modules LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 26)
set(CMAKE_CXX_SCAN_FOR_MODULES ON)
set(CMAKE_CXX_MODULE_STD ON)
set(FMT_MODULE ON)
add_subdirectory(fmt)
add_executable(main
source/main.cpp
)
target_link_libraries(main fmt::fmt)This is my GCC version:
gcc (GCC) 15.2.1 20251112
If I try to format say, an int or a std::vector<int>, then everything compiles correctly. However upon trying to format std::chrono::seconds(600), I get a fairly long compilation error:
Error Output
/usr/bin/c++ -I/home/keenan/Documents/test/modules/fmt/include -std=gnu++26 -fmodules-ts -MD -MT CMakeFiles/main.dir/source/main.cpp.o -MF CMakeFiles/main.dir/source/main.cpp.o.d -fmodules-ts -fmodule-mapper=CMakeFiles/main.dir/source/main.cpp.o.modmap -MD -fdeps-format=p1689r5 -x c++ -o CMakeFiles/main.dir/source/main.cpp.o -c /home/keenan/Documents/test/modules/source/main.cpp
In file included from /home/keenan/Documents/test/modules/fmt/include/fmt/format.h:41,
from /home/keenan/Documents/test/modules/fmt/include/fmt/args.h:17,
from /home/keenan/Documents/test/modules/fmt/src/fmt.cc:119,
of module fmt, imported at /home/keenan/Documents/test/modules/source/main.cpp:2:
/home/keenan/Documents/test/modules/fmt/include/fmt/base.h: In instantiation of ‘fmt::v12::fstring@fmt<T>::fstring(const S&) [with S = fmt::v12::detail::write_floating_seconds@fmt<std::chrono::duration<long unsigned int, std::ratio<1> > >(fmt::v12::memory_buffer@fmt&, std::chrono::duration<long unsigned int, std::ratio<1> >, int)::<lambda()>::FMT_COMPILE_STRING; typename std::enable_if<(std::is_base_of<fmt::v12::detail::compile_string@fmt, S>::value && std::is_same<typename S::char_type, char>::value), int>::type <anonymous> = 0; T = {double, int&}]’:
/home/keenan/Documents/test/modules/fmt/include/fmt/chrono.h:1038:43: required from ‘void fmt::v12::detail::write_floating_seconds@fmt(fmt::v12::memory_buffer@fmt&, Duration, int) [with Duration = std::chrono::duration<long unsigned int, std::ratio<1> >; fmt::v12::memory_buffer@fmt = fmt::v12::basic_memory_buffer@fmt<char>]’
4238 | [] { \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4239 | /* Use the hidden visibility as a workaround for a GCC bug (#1973). */ \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4240 | /* Use a macro-like name to avoid shadowing warnings. */ \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4241 | struct FMT_VISIBILITY("hidden") FMT_COMPILE_STRING : base { \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4242 | using char_type = fmt::remove_cvref_t<decltype(s[0])>; \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4243 | constexpr explicit operator fmt::basic_string_view<char_type>() \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4244 | const { \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4245 | return fmt::detail::compile_string_to_view<char_type>(s); \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4246 | } \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4247 | }; \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4248 | using FMT_STRING_VIEW = \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4249 | fmt::basic_string_view<typename FMT_COMPILE_STRING::char_type>; \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4250 | fmt::detail::ignore_unused(FMT_STRING_VIEW(FMT_COMPILE_STRING())); \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4251 | return FMT_COMPILE_STRING(); \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4252 | }()
| ~^~
/home/keenan/Documents/test/modules/fmt/include/fmt/chrono.h:1781:31: required from ‘void fmt::v12::detail::duration_formatter@fmt<Char, Rep, Period>::on_second(fmt::v12::detail::numeric_system@fmt, fmt::v12::detail::pad_type@fmt) [with Char = char; Rep = long int; Period = std::ratio<1>]’
1781 | write_floating_seconds(buf, std::chrono::duration<rep, Period>(val),
| ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1782 | precision);
| ~~~~~~~~~~
/home/keenan/Documents/test/modules/fmt/include/fmt/chrono.h:706:32: required from ‘constexpr const Char* fmt::v12::detail::parse_chrono_format@fmt(const Char*, const Char*, Handler&&) [with Char = char; Handler = duration_formatter@fmt<char, long int, std::ratio<1> >&]’
706 | case 'S': handler.on_second(numeric_system::standard, pad); break;
| ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/keenan/Documents/test/modules/fmt/include/fmt/chrono.h:2096:34: required from ‘decltype (ctx.out()) fmt::v12::formatter@fmt<std::chrono::duration<_Rep1, _Period1>, Char>::format(std::chrono::duration<_Rep1, _Period1>, FormatContext&) const [with FormatContext = fmt::v12::context@fmt; Rep = long int; Period = std::ratio<1>; Char = char; decltype (ctx.out()) = fmt::v12::basic_appender@fmt<char>]’
2096 | detail::parse_chrono_format(begin, end, f);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
/home/keenan/Documents/test/modules/fmt/include/fmt/base.h:2322:29: required from ‘static void fmt::v12::detail::value@fmt<Context>::format_custom(void*, fmt::v12::parse_context@fmt<typename Context::char_type>&, Context&) [with T = std::chrono::duration<long int>; Context = fmt::v12::context@fmt; typename Context::char_type = char]’
2322 | ctx.advance_to(cf.format(*static_cast<qualified_type*>(arg), ctx));
| ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/keenan/Documents/test/modules/fmt/include/fmt/base.h:2302:19: required from ‘constexpr fmt::v12::detail::value@fmt<Context>::value(T&, fmt::v12::detail::custom_tag@fmt) [with T = std::chrono::duration<long int>; typename std::enable_if<has_formatter<T, typename Context::char_type>(), int>::type <anonymous> = 0; Context = fmt::v12::context@fmt]’
2302 | custom.format = format_custom<value_type>;
| ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/keenan/Documents/test/modules/fmt/include/fmt/base.h:2282:65: required from ‘constexpr fmt::v12::detail::value@fmt<Context>::value(T&) [with T = std::chrono::duration<long int>; typename std::enable_if<(std::integral_constant<bool, (((((((std::is_class<T>::value || std::is_enum<T>::value) || std::is_union<T>::value) || std::is_array<_Up>::value) && (! fmt::v12::detail::has_to_string_view@fmt<T, void>::value)) && (! fmt::v12::detail::is_named_arg@fmt<T>::value)) && (! fmt::v12::detail::use_format_as@fmt<T>::value)) && (! fmt::v12::detail::use_format_as_member@fmt<typename std::remove_const<_Tp>::type, std::integral_constant<bool, true> >::value))>::value || (!1)), int>::type <anonymous> = 0; Context = fmt::v12::context@fmt]’
2282 | FMT_CONSTEXPR20 FMT_INLINE value(T& x) : value(x, custom_tag()) {}
| ^
/home/keenan/Documents/test/modules/fmt/include/fmt/base.h:2989:15: required from ‘void fmt::v12::println@fmt(FILE*, format_string<T ...>, T&& ...) [with T = {std::chrono::duration<long int, std::ratio<1, 1> >}; FILE = FILE; format_string<T ...> = fstring@fmt<std::chrono::duration<long int, std::ratio<1, 1> > >]’
2989 | vargs<T...> va = {{args...}};
| ^~
/home/keenan/Documents/test/modules/fmt/include/fmt/base.h:2999:22: required from ‘void fmt::v12::println@fmt(format_string<T ...>, T&& ...) [with T = {std::chrono::duration<long int, std::ratio<1, 1> >}; format_string<T ...> = fstring@fmt<std::chrono::duration<long int, std::ratio<1, 1> > >]’
2999 | return fmt::println(stdout, fmt, static_cast<T&&>(args)...);
| ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/keenan/Documents/test/modules/source/main.cpp:5:17: required from here
5 | fmt::println("Test: {}", std::chrono::seconds(600));
| ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/keenan/Documents/test/modules/fmt/include/fmt/base.h:2785:29: error: ‘parse_format_string’ was not declared in this scope
2785 | (parse_format_string(sv, checker(sv, arg_pack())), 0);
| ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/keenan/Documents/test/modules/fmt/include/fmt/base.h: In instantiation of ‘fmt::v12::fstring@fmt<T>::fstring(const S&) [with S = fmt::v12::detail::write_floating_seconds@fmt<std::chrono::duration<long int> >(fmt::v12::memory_buffer@fmt&, std::chrono::duration<long int>, int)::<lambda()>::FMT_COMPILE_STRING; typename std::enable_if<(std::is_base_of<fmt::v12::detail::compile_string@fmt, S>::value && std::is_same<typename S::char_type, char>::value), int>::type <anonymous> = 0; T = {double, int&}]’:
/home/keenan/Documents/test/modules/fmt/include/fmt/chrono.h:1038:43: required from ‘void fmt::v12::detail::write_floating_seconds@fmt(fmt::v12::memory_buffer@fmt&, Duration, int) [with Duration = std::chrono::duration<long int>; fmt::v12::memory_buffer@fmt = fmt::v12::basic_memory_buffer@fmt<char>]’
4238 | [] { \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4239 | /* Use the hidden visibility as a workaround for a GCC bug (#1973). */ \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4240 | /* Use a macro-like name to avoid shadowing warnings. */ \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4241 | struct FMT_VISIBILITY("hidden") FMT_COMPILE_STRING : base { \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4242 | using char_type = fmt::remove_cvref_t<decltype(s[0])>; \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4243 | constexpr explicit operator fmt::basic_string_view<char_type>() \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4244 | const { \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4245 | return fmt::detail::compile_string_to_view<char_type>(s); \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4246 | } \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4247 | }; \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4248 | using FMT_STRING_VIEW = \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4249 | fmt::basic_string_view<typename FMT_COMPILE_STRING::char_type>; \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4250 | fmt::detail::ignore_unused(FMT_STRING_VIEW(FMT_COMPILE_STRING())); \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4251 | return FMT_COMPILE_STRING(); \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4252 | }()
| ~^~
/home/keenan/Documents/test/modules/fmt/include/fmt/chrono.h:1422:33: required from ‘void fmt::v12::detail::tm_writer@fmt<OutputIt, Char, Duration>::on_second(fmt::v12::detail::numeric_system@fmt, fmt::v12::detail::pad_type@fmt) [with OutputIt = fmt::v12::basic_appender@fmt<char>; Char = char; Duration = std::chrono::duration<long int>]’
1422 | write_floating_seconds(buf, *subsecs_);
| ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~
/home/keenan/Documents/test/modules/fmt/include/fmt/chrono.h:1796:21: required from ‘void fmt::v12::detail::duration_formatter@fmt<Char, Rep, Period>::on_second(fmt::v12::detail::numeric_system@fmt, fmt::v12::detail::pad_type@fmt) [with Char = char; Rep = long int; Period = std::ratio<1>]’
1796 | format_tm(time, &tm_writer_type::on_second, ns, pad);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
/home/keenan/Documents/test/modules/fmt/include/fmt/chrono.h:706:32: required from ‘constexpr const Char* fmt::v12::detail::parse_chrono_format@fmt(const Char*, const Char*, Handler&&) [with Char = char; Handler = duration_formatter@fmt<char, long int, std::ratio<1> >&]’
706 | case 'S': handler.on_second(numeric_system::standard, pad); break;
| ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/keenan/Documents/test/modules/fmt/include/fmt/chrono.h:2096:34: required from ‘decltype (ctx.out()) fmt::v12::formatter@fmt<std::chrono::duration<_Rep1, _Period1>, Char>::format(std::chrono::duration<_Rep1, _Period1>, FormatContext&) const [with FormatContext = fmt::v12::context@fmt; Rep = long int; Period = std::ratio<1>; Char = char; decltype (ctx.out()) = fmt::v12::basic_appender@fmt<char>]’
2096 | detail::parse_chrono_format(begin, end, f);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
/home/keenan/Documents/test/modules/fmt/include/fmt/base.h:2322:29: required from ‘static void fmt::v12::detail::value@fmt<Context>::format_custom(void*, fmt::v12::parse_context@fmt<typename Context::char_type>&, Context&) [with T = std::chrono::duration<long int>; Context = fmt::v12::context@fmt; typename Context::char_type = char]’
2322 | ctx.advance_to(cf.format(*static_cast<qualified_type*>(arg), ctx));
| ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/keenan/Documents/test/modules/fmt/include/fmt/base.h:2302:19: required from ‘constexpr fmt::v12::detail::value@fmt<Context>::value(T&, fmt::v12::detail::custom_tag@fmt) [with T = std::chrono::duration<long int>; typename std::enable_if<has_formatter<T, typename Context::char_type>(), int>::type <anonymous> = 0; Context = fmt::v12::context@fmt]’
2302 | custom.format = format_custom<value_type>;
| ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/keenan/Documents/test/modules/fmt/include/fmt/base.h:2282:65: required from ‘constexpr fmt::v12::detail::value@fmt<Context>::value(T&) [with T = std::chrono::duration<long int>; typename std::enable_if<(std::integral_constant<bool, (((((((std::is_class<T>::value || std::is_enum<T>::value) || std::is_union<T>::value) || std::is_array<_Up>::value) && (! fmt::v12::detail::has_to_string_view@fmt<T, void>::value)) && (! fmt::v12::detail::is_named_arg@fmt<T>::value)) && (! fmt::v12::detail::use_format_as@fmt<T>::value)) && (! fmt::v12::detail::use_format_as_member@fmt<typename std::remove_const<_Tp>::type, std::integral_constant<bool, true> >::value))>::value || (!1)), int>::type <anonymous> = 0; Context = fmt::v12::context@fmt]’
2282 | FMT_CONSTEXPR20 FMT_INLINE value(T& x) : value(x, custom_tag()) {}
| ^
/home/keenan/Documents/test/modules/fmt/include/fmt/base.h:2989:15: required from ‘void fmt::v12::println@fmt(FILE*, format_string<T ...>, T&& ...) [with T = {std::chrono::duration<long int, std::ratio<1, 1> >}; FILE = FILE; format_string<T ...> = fstring@fmt<std::chrono::duration<long int, std::ratio<1, 1> > >]’
2989 | vargs<T...> va = {{args...}};
| ^~
/home/keenan/Documents/test/modules/fmt/include/fmt/base.h:2999:22: required from ‘void fmt::v12::println@fmt(format_string<T ...>, T&& ...) [with T = {std::chrono::duration<long int, std::ratio<1, 1> >}; format_string<T ...> = fstring@fmt<std::chrono::duration<long int, std::ratio<1, 1> > >]’
2999 | return fmt::println(stdout, fmt, static_cast<T&&>(args)...);
| ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/keenan/Documents/test/modules/source/main.cpp:5:17: required from here
5 | fmt::println("Test: {}", std::chrono::seconds(600));
| ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/keenan/Documents/test/modules/fmt/include/fmt/base.h:2785:29: error: ‘parse_format_string’ was not declared in this scope
2785 | (parse_format_string(sv, checker(sv, arg_pack())), 0);
| ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The error no longer occurs if I remove the use of FMT_STRING here, though I suspect that the underlying issue is that FMT_STRING yields an object of a type defined inside an immediately-invoked lambda. Removing the FMT_VISIBILITY("hidden") did not seem to change anything, though that was just a blind attempt to see if that could be the issue.
Metadata
Metadata
Assignees
Labels
No labels