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

            Bug ID: 107437
           Summary: nested generic lambdas fail requiring unneded captures
           Product: gcc
           Version: 12.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: development at jordi dot vilar.cat
  Target Milestone: ---

This simple valid code fails to compile with all recent versions of gcc, but
compiles nicely with clang (and even msvc!)

(live demo on complier explorer: https://godbolt.org/z/eM1b9e6s9)

// compile with just -std=c++20
#include <array>
#include <functional>
#include <type_traits>

void test()
{
    std::invoke([]<typename T>(auto N, std::type_identity<T>)
    {
        using vector_type = std::array<T, N>;
        static_assert(N == std::tuple_size_v<vector_type>);
        std::invoke([]<std::size_t... i>(std::index_sequence<i...>)
        {
           
static_assert(std::conjunction_v<std::is_same<std::tuple_element_t<i,
vector_type>, T>...>);
        }, std::make_index_sequence<N>{});
    }, std::integral_constant<std::size_t, 3>{}, std::type_identity<int>{});
}

It issues the diagnostics output:
<source>: In instantiation of 'test()::<lambda(auto:3, std::type_identity<T>)>
[with T = int; auto:3 = std::integral_constant<long unsigned int, 3>]':
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/type_traits:2565:26:  
required by substitution of 'template<class _Fn, class ... _Args> static
std::__result_of_success<decltype (declval<_Fn>()((declval<_Args>)()...)),
std::__invoke_other> std::__result_of_other_impl::_S_test(int) [with _Fn =
test()::<lambda(auto:3, std::type_identity<T>)>; _Args =
{std::integral_constant<long unsigned int, 3>, std::type_identity<int>}]'
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/type_traits:2576:55:  
required from 'struct std::__result_of_impl<false, false,
test()::<lambda(auto:3, std::type_identity<T>)>, std::integral_constant<long
unsigned int, 3>, std::type_identity<int> >'
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/type_traits:2581:12:  
required from 'struct std::__invoke_result<test()::<lambda(auto:3,
std::type_identity<T>)>, std::integral_constant<long unsigned int, 3>,
std::type_identity<int> >'
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/type_traits:3022:12:  
required from 'struct std::invoke_result<test()::<lambda(auto:3,
std::type_identity<T>)>, std::integral_constant<long unsigned int, 3>,
std::type_identity<int> >'
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/type_traits:3034:11:  
required by substitution of 'template<class _Fn, class ... _Args> using
invoke_result_t = typename std::invoke_result::type [with _Fn =
test()::<lambda(auto:3, std::type_identity<T>)>; _Args =
{std::integral_constant<long unsigned int, 3>, std::type_identity<int>}]'
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/functional:107:5:  
required by substitution of 'template<class _Callable, class ... _Args>
constexpr std::invoke_result_t<_Fn, _Args ...> std::invoke(_Callable&&, _Args&&
...) [with _Callable = test()::<lambda(auto:3, std::type_identity<T>)>; _Args =
{std::integral_constant<long unsigned int, 3>, std::type_identity<int>}]'
<source>:7:16:   required from here
<source>:13:32: error: 'N' is not captured
   13 |            
static_assert(std::conjunction_v<std::is_same<std::tuple_element_t<i,
vector_type>, T>...>);
      |                          
~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:11:21: note: the lambda has no capture-default
   11 |         std::invoke([]<std::size_t... i>(std::index_sequence<i...>)
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   12 |         {
      |         ~            
   13 |            
static_assert(std::conjunction_v<std::is_same<std::tuple_element_t<i,
vector_type>, T>...>);
      |            
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   14 |         }, std::make_index_sequence<N>{});
      |         ~            
<source>:7:37: note: 'std::integral_constant<long unsigned int, 3> N' declared
here
    7 |     std::invoke([]<typename T>(auto N, std::type_identity<T>)
      |                                ~~~~~^

Reply via email to