https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104792
Bug ID: 104792 Summary: [g++ and/or libstdc++] Wunused-local-typedefs + C++20 concepts = annoying Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: arthur.j.odwyer at gmail dot com Target Milestone: --- This might be considered "not a bug", or "duplicate of #61596", or "bug but in a different way from what Arthur suggests," so I'm going to give the non-reduced test case and let one of you (@jwakely perhaps) worry about how to reduce it. // https://godbolt.org/z/v9Wv8vY3G #include <iterator> void test() { struct It { using value_type = int; using difference_type = int; int& operator*() const; It& operator++(); // X It operator++(int); // X }; static_assert(std::is_same_v<std::iter_value_t<It>, int>); static_assert(std::is_same_v<std::iter_rvalue_reference_t<It>, int&&>); } Compile with "g++ -std=c++20 -W -Wall" and libstdc++. GCC will give a warning: warning: typedef 'using difference_type = int' locally defined but not used [-Wunused-local-typedefs] 6 | using difference_type = int; | ^~~~~~~~~~~~~~~ However, if you then delete any of the three lines marked "X", the warning will go away again. I believe this is because `iter_value_t<It>` relies on a C++20 Concepts constraint where `difference_type` *is* checked when `It` is an `input_iterator`, but is *not* checked when `It` is not an iterator. So, when these precise three operators exist, the typedef isn't unused, but when any one of them doesn't exist, GCC gives the unused-typedef warning. I claim that the user-programmer shouldn't be responsible for tracking the internal implementation details of the constraints of `std::iter_value_t`. I just want to make a local type that has all the pieces of an iterator, without GCC helpfully getting in the way and warning me that *right now* (according to the internal implementation details of libstdc++) some of those pieces aren't being used. I admit that in this case the warning is surfaced only when I *fail* to implement one of those three member functions, so I actually have *not* implemented "all the pieces of an iterator" in this test case. I'm betting that it's possible to reproduce this annoying issue, somewhere in libstdc++, even without that caveat, though. For now, I'll silence the warning by removing my unused typedef `difference_type`, i.e. #include <iterator> void test() { struct It { using value_type = int; int& operator*() const; }; static_assert(std::is_same_v<std::iter_value_t<It>, int>); static_assert(std::is_same_v<std::iter_rvalue_reference_t<It>, int&&>); } But I'm uncomfortable with that, because I don't know if later revisions/bugfixes to the library will require me to re-add those pieces I've removed.