https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90943
Bug ID: 90943 Summary: Visiting inherited variants no longer works in 9.1 Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: barry.revzin at gmail dot com Target Milestone: --- Here's a short repro: #include <variant> struct V : std::variant<int> { using std::variant<int>::variant; }; namespace std { template <> struct variant_size<V> : integral_constant<size_t, 1> { }; template <> struct variant_alternative<0, V> { using type = int; }; } V v = 42; int i = std::visit([](int){ return 17;}, v); This worked fine in gcc 8, but breaks in gcc 9 with: In file included from <source>:1: /opt/compiler-explorer/gcc-9.1.0/include/c++/9.1.0/variant: In instantiation of 'constexpr const bool std::__detail::__variant::_Extra_visit_slot_needed<int, V&>::value': /opt/compiler-explorer/gcc-9.1.0/include/c++/9.1.0/variant:809:50: required from 'constexpr const int std::__detail::__variant::_Multi_array<int (*)(<lambda(int)>&&, V&), 1>::__do_cookie' /opt/compiler-explorer/gcc-9.1.0/include/c++/9.1.0/variant:821:53: required from 'struct std::__detail::__variant::_Multi_array<int (*)(<lambda(int)>&&, V&), 1>' /opt/compiler-explorer/gcc-9.1.0/include/c++/9.1.0/variant:1016:36: required from 'struct std::__detail::__variant::__gen_vtable<true, int, <lambda(int)>&&, V&>' /opt/compiler-explorer/gcc-9.1.0/include/c++/9.1.0/variant:1637:23: required from 'constexpr decltype(auto) std::__do_visit(_Visitor&&, _Variants&& ...) [with bool __use_index = false; bool __same_return_types = true; _Visitor = <lambda(int)>; _Variants = {V&}]' /opt/compiler-explorer/gcc-9.1.0/include/c++/9.1.0/variant:1653:24: required from 'constexpr decltype(auto) std::visit(_Visitor&&, _Variants&& ...) [with _Visitor = <lambda(int)>; _Variants = {V&}]' <source>:21:43: required from here /opt/compiler-explorer/gcc-9.1.0/include/c++/9.1.0/variant:778:5: error: incomplete type 'std::__detail::__variant::_Extra_visit_slot_needed<int, V&>::_Variant_never_valueless<V>' used in nested name specifier 778 | && !_Variant_never_valueless<__remove_cvref_t<_Variant>>::value; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ I realize that this kind of stuff isn't technically or officially sanctioned -- but doing this makes it very convenient to write an easy-to-use recursive variant without having to implement our own variant. Tim says you should call this NAD, but I'm being pretty optimistic :-)