The v2 patch extends the change to std::basic_stacktrace::iterator. Tested x86_64-linux. Pushed to trunk.
-- >8 -- Because std::span<Incomplete> can be useful, it makes sense to define std::span<Incomplete>::iterator such that Incomplete is not an associated class, and so the compiler won't attempt to complete it when doing ADL for span iterators (including during the definition of std::span<Incomplete>::const_iterator which checks that iterator satisfies std::input_or_output_iterator). We can't make this change for std::vector<Incomplete> because it would change the mangled name of std::vector<Incomplete>::iterator which would affect the mangled names of templates and functions written by users. We can do the same thing for std::basic_stacktrace<Alloc> just so that Alloc is not an associated class. This is probably less beneficial, as Alloc can't be incomplete, and using SomeAllocator<Incomplete> as the allocator parameter doesn't seem useful. But simply making the stacktrace iterator not use Alloc for ADL lookup seems worthwhile. This is doable because std::stacktrace is part of C++23 so its ABI isn't considered stable yet. libstdc++-v3/ChangeLog: * include/std/span (span::__iter_tag): Declare nested type. (span::iterator): Use __iter_tag as second template argument. * include/std/stacktrace (basic_stacktrace::iterator): Use _Impl as second template argument. --- libstdc++-v3/include/std/span | 5 ++++- libstdc++-v3/include/std/stacktrace | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span index 00fc5279152..b7392a0500e 100644 --- a/libstdc++-v3/include/std/span +++ b/libstdc++-v3/include/std/span @@ -123,6 +123,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using __is_compatible_ref = __is_array_convertible<_Type, remove_reference_t<_Ref>>; + // Nested type so that _Type is not an associated class of iterator. + struct __iter_tag; + public: // member types using element_type = _Type; @@ -133,7 +136,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using const_pointer = const _Type*; using reference = element_type&; using const_reference = const element_type&; - using iterator = __gnu_cxx::__normal_iterator<pointer, span>; + using iterator = __gnu_cxx::__normal_iterator<pointer, __iter_tag>; using reverse_iterator = std::reverse_iterator<iterator>; #if __cplusplus > 202002L using const_iterator = std::const_iterator<iterator>; diff --git a/libstdc++-v3/include/std/stacktrace b/libstdc++-v3/include/std/stacktrace index cd2606257fe..cdd1276d212 100644 --- a/libstdc++-v3/include/std/stacktrace +++ b/libstdc++-v3/include/std/stacktrace @@ -179,13 +179,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { using _AllocTraits = allocator_traits<_Allocator>; using uintptr_t = __UINTPTR_TYPE__; + struct _Impl; public: using value_type = stacktrace_entry; using const_reference = const value_type&; using reference = value_type&; using const_iterator - = __gnu_cxx::__normal_iterator<value_type*, basic_stacktrace>; + = __gnu_cxx::__normal_iterator<typename _AllocTraits::const_pointer, + _Impl>; using iterator = const_iterator; using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; -- 2.46.0