`<filesystem>`: compiler error using `directory_iterator`/`recursive_directory_iterator` inside a struct/class with modules
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 11.1k
- Forks
- 1.7k
- Avg merge
- 4d 15h
- Merged PRs (30d)
- 22
Description
Describe the bug
when recursive_directory_iterator or directory_iterator is used inside a modules export block, the following code will compile; if this same code is then wrapped by a struct/class the code will never compile when the method is called with the following issue(s) of 2 depending on the code setup:
-
missing std::partial_order from
#<compare>, although if this header is included (which should not be required) the following error will happen instead
..\include\type_traits(2118,13): error C2678: binary '&': no operator found which takes a left-hand operand of type '_Bitmask' (or there is no acceptable conversion)
with
[
_Bitmask=__std_fs_file_attr
]
Command-line test case
main.cpp
#include <compare>
import brokenIter;
int main() {
/*
without #include <compare> code will complain about missing std::partial_order from #compare
with #include <compare> the code during build output will generate the given error (which is also reflected as a compile error):
..\include\type_traits(2118,13): error C2678: binary '&': no operator found which takes a left-hand operand of type '_Bitmask' (or there is no acceptable conversion)
with
[
_Bitmask=__std_fs_file_attr
]
*/
//the problem functions defined are the 2 below, a static or non static method both exibits the compile error described above
thing thingO = thing();
thingO.iterDirBroken1();
thing::iterDirBroken2();
//the following function will work though if the previous 2 are not compiled
noStructIter();
return 0;
}
brokenIter.ixx
module;
#include <filesystem>
export module brokenIter;
export{
struct thing {
void iterDirBroken1() {
for (const auto& i : std::filesystem::recursive_directory_iterator(".")) {
}
}
inline static void iterDirBroken2() {
for (const auto& i : std::filesystem::recursive_directory_iterator(".")) {
}
}
};
void noStructIter(){
for (const auto& i : std::filesystem::recursive_directory_iterator(".")) {
}
}
}
compile command:
cl /EHsc /W4 /WX /std:c++latest .\brokenIter.ixx .\main.cpp
Expected behavior
code does not compile with or without #<compare> due to struct/class method using recursive_directory_iterator or directory_iterator
(if you remove #<compare> there will be a different compile error which still is not supposed to be there)
STL version
Microsoft Visual Studio Community 2022
Version 17.6.0 Preview 4.0 although the behavior happened on 17.5.4, and 17.6 Preview 2.0, and Preview 3.0
Additional context
exact same (minimum reproducible code) I used to get a compile error: https://github.com/16-Bit-Dog/BrokenFileSystemOn17.6
same compiler issue but elaborated upon in relation to #3330
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the failure with the command in the issue using main.cpp and brokenIter.ixx, comparing the struct methods with noStructIter(). Check the related discussion in issue #3330 and the reported errors involving and type_traits; done means directory_iterator and recursive_directory_iterator compile inside the exported struct with and without the extra header.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100