https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122576

            Bug ID: 122576
           Summary: __is_fast_hash<hash<variant<type...>>> always true
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: yfeldblum at gmail dot com
  Target Milestone: ---

`__is_fast_hash` is generally queried for, and expected to be specialized for,
specializations of `hash`. For example, `unordered_set<value_type, hasher>`
will query `__is_fast_hash<hasher>::value` and not
`__is_fast_hash<value_type>`.

That is what `__is_fast_hash<hash<variant<type...>>>` should do as well - it
should query `__is_fast_hash<hash<type>>...`.

However, it only queries `__is_fast_hash<type>...`, which is not expected.

It is intended that `unordered_set<string_view>` cache hash codes, and that
`unordered_set<variant<string_view>>` also cache hash codes. However, only the
former will caches hash codes. The latter does not.

Repro (https://www.godbolt.org/z/b1zG8q3xe):
```
#include <functional>
#include <string_view>
#include <variant>

template <typename T>
constexpr bool fast = // helper
    std::__is_fast_hash<std::hash<T>>::value;

static_assert(fast<int>); // sanity
static_assert(!fast<long double>); // sanity
static_assert(!fast<std::string_view>); // <--- works
static_assert(!fast<std::variant<std::string_view>>); // <--- broken
```
```
<source>:12:15: error: static assertion failed
   12 | static_assert(!fast<std::variant<std::string_view>>); // <--- broken
      |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```

Since gcc-8 until present (at least gcc-15).

Introduced in f78958c9b421bba1f24d04ec47cfa3d999214b32
(https://github.com/gcc-mirror/gcc/commit/f78958c9b421bba1f24d04ec47cfa3d999214b32).

Reply via email to