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