STL icon indicating copy to clipboard operation
STL copied to clipboard

`<filesystem>`: compiler error using `directory_iterator`/`recursive_directory_iterator` inside a struct/class with modules

Open 16-Bit-Dog opened this issue 2 years ago • 6 comments
trafficstars

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:

  1. 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

16-Bit-Dog avatar Apr 18 '23 19:04 16-Bit-Dog

FYI @cdacamar this looks like a compiler bug.

StephanTLavavej avatar Apr 19 '23 21:04 StephanTLavavej

I observe that this works if broken_iter.ixx says import std;.

StephanTLavavej avatar Jul 19 '23 19:07 StephanTLavavej

The following imports should not be required though, no?

16-Bit-Dog avatar Jul 19 '23 21:07 16-Bit-Dog

This is still present in 17.8. I noticed that by replacing #include <compare> with #include <filesystem> in your example, there are no errors. Whatever that means.

In my case, the problem occurs when using std::filesystem:exists() in a member function in a class in module. Indeed, if I replace the content of the functions of your example with std::filesystem::exists("."); I get the same error. The workaround mentioned above works in this minimal example, but not in my real code.

matlimatli avatar Nov 16 '23 13:11 matlimatli

Using #include <filesystem> at the module import location (in the global module fragment, if necessary) definitely fixes the issue for me.

oliverportcnc avatar Feb 05 '24 20:02 oliverportcnc

Does this still repro with VS 2022 17.10 or later? I improved the STL so that include-before-import (but not the other order) works, with #4154 in VS 2022 17.10.

StephanTLavavej avatar May 10 '24 20:05 StephanTLavavej

I can reproduce this problem with VS 2022 17.10.3

JulZimmermann avatar Jun 21 '24 06:06 JulZimmermann