https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106201
--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Jonathan Wakely from comment #1) > The third one fails but not because of anything to do with borrowable > ranges. The problem is that the filesystem::swap(path&, path&) overload is > found by ADL and considered by overload resolution when checking whether > counted_iterator<filesystem::directory_iterator> is swappable. Overload > resolution checks whether the iterator can be converted to a path, which > causes constraint recursion. The full explanation is that views::take creates a view whose iterator is counted_iterator<filesystem::directory_iterator> and the constraints for ranges::for_each check that that iterator is copyable, movable, and swappable. That fails with libstdc++: #include <filesystem> #include <ranges> using I = std::counted_iterator<std::filesystem::directory_iterator>; static_assert( std::swappable<I> ); The swappable concept finds filesystem::swap(path&, path&) via ADL. Overload resolution checks if counted_iterator<filesystem::directory_iterator> can be converted to path, which considers the path constructors, which checks if counted_iterator is an iterator, which uses std::iterator_traits, which depends on the iterator being copyable, which depends on it being swappable, and we're recursing. However, I *think* there's a compiler bug here. We should not be considering constructors of path to see if we can get a path& lvalue. That would never work, constructing a path would give us an rvalue. Clang compiles the example when using libstdc++ headers. Clang and EDG both compile this, but G++ doesn't: namespace effing { template<typename T> concept effable = requires (T& t) { f(t); }; template <class T> requires effable<T> || true void eff(T&&) { } } struct path { template<effing::effable T> path(const T&) { } }; void f(path&); struct iterator { }; int main() { iterator i; effing::eff(i); } conv.C: In substitution of 'template<class T> requires effable<T> path::path(const T&) [with T = iterator]': conv.C:4:42: recursively required by substitution of 'template<class T> requires effable<T> path::path(const T&) [with T = iterator]' conv.C:4:42: required by substitution of 'template<class T> requires (effable<T>) || true void effing::eff(T&&) [with T = iterator&]' conv.C:22:14: required from here conv.C:4:13: required for the satisfaction of 'effable<T>' [with T = iterator] conv.C:4:23: in requirements with 'T& t' [with T = iterator] conv.C:4:23: error: satisfaction of atomic constraint 'requires(T& t) {f(t);} [with T = T]' depends on itself 4 | concept effable = requires (T& t) { f(t); }; | ^~~~~~~~~~~~~~~~~~~~~~~~~