header in .cpp files using that module" is caused by a compiler bug where the compiler is curr...">

Compiler bug workaround for using format() in a user-defined module by StephanTLavavej · Pull Request #4919 · microsoft/STL (original) (raw)

DevCom-10313766 VSO-1775715 "Using std::format in a module requires including <format> header in .cpp files using that module" is caused by a compiler bug where the compiler is currently unable to encode UDLs in the IFC. The workaround is to avoid UDLs. Constructing temporaries of length 2 or 1 was the simplest, compared to extracting named constexpr variables.

Since the workaround is relatively simple but affects several lines, I chose to make it unconditional (instead of guarding it for MSVC only), and I commented only the first occurrence (no reason to repeat it on every line). My hope is that the compiler will be fixed very soon (@cdacamar is investigating).

I audited the STL for other UDLs in our headers, and <filesystem> was the only other user of UDLs. However, all of its usage was in non-templated functions, which appear to be immune to the compiler bug, so I don't believe that <filesystem> changes are necessary.

This scenario, where the STL is included in the Global Module Fragment of a user-defined module, is clearly under-explored - along the way I encountered and reported the much more severe VSO-2227713 "Modules: Exported function templates can't use std::cout properly" (with no known workaround). So, I'm adding a dedicated test for this scenario, currently just exercising the format() scenario but available to extend in the future. I had to extract P2465R3_standard_library_modules/env.lst (because we have to handle the usually-force-included machinery specially, and can't tolerate /permissive, we need dedicated configurations).

This requires special Python and Perl machinery to compile the user.ixx before the test.cpp, but very similar to existing tests that we have elsewhere. I verified both the GitHub Python and internal Perl test harnesses, both positively (test passes with product changes) and negatively (test fails without product changes).