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

Reply via email to