<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/61443>61443</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Issue with clang compilation of code using std::function and std::variant
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          DD-L
      </td>
    </tr>
</table>

<pre>
    
Hello, can someone explain this?

```
#include <functional>
#include <variant>

struct P;

struct A : std::function<P(void)> {
    using std::function<P(void)>::function;
    // ...
};


struct P {
    std::variant<int, A> m_member;
};

int main() {
    // ...
    return 0;
}
```


The above code can be compiled successfully on all gcc/MSVC versions that support `std::function` and `std::variant`: [`https://godbolt.org/z/jb9TzsGeG`](https://godbolt.org/z/jb9TzsGeG). 

However, all versions of clang (`<= ver 15.0.0`) report the following error:

```
In file included from <source>:4:
In file included from /opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/functional:49:
In file included from /opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_function.h:60:
In file included from /opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/move.h:57:
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/type_traits:2936:63: error: calling '_S_get' with incomplete return type 'typename __invoke_result<A &>::type' (aka 'P')
      template<typename _Tp, typename = decltype(_S_conv<_Tp>(_S_get()))>
 ^~~~~~~~
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/std_function.h:349:4: note: in instantiation of template class 'std::__is_invocable_impl<std::__invoke_result<A &>, P, false>' requested here
        : __is_invocable_impl<_Res2, _Res>::type
 ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/std_function.h:353:34: note: in instantiation of template class 'std::function<P ()>::_Callable<A, A>' requested here
        using _Requires = __enable_if_t<_Cond::value, _Tp>;
 ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/std_function.h:434:33: note: in instantiation of template type alias '_Requires' requested here
 typename _Constraints = _Requires<_Callable<_Functor>>>
 ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/std_function.h:435:2: note: in instantiation of default argument for 'function<A>' required here
        function(_Functor&& __f)
 ^~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/type_traits:1297:4: note: while substituting deduced template arguments into function template 'function' [with _Functor = A, _Constraints = (no value)]
 __is_trivially_constructible(_Tp, _Tp&&)>>
 ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/type_traits:1303:14: note: (skipping 3 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
    : public __is_trivially_move_constructible_impl<_Tp>
 ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/variant:350:23: note: in instantiation of static data member 'std::__detail::__variant::_Traits<int, A>::_S_trivial_move_ctor' requested here
          _S_trivial_dtor && _S_trivial_move_ctor
 ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/variant:732:45: note: in instantiation of static data member 'std::__detail::__variant::_Traits<int, A>::_S_trivial_move_assign' requested here
      _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign, _Types...>;
 ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/variant:735:28: note: in instantiation of template type alias '_Move_assign_alias' requested here
    struct _Variant_base : _Move_assign_alias<_Types...>
 ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/variant:1337:15: note: in instantiation of template class 'std::__detail::__variant::_Variant_base<int, A>' requested here
    : private __detail::__variant::_Variant_base<_Types...>,
 ^
<source>:16:26: note: in instantiation of template class 'std::variant<int, A>' requested here
    std::variant<int, A> m_member;
 ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/type_traits:2930:37: note: '_S_get' declared here
      static typename _Result::type _S_get();
                                    ^
<source>:15:8: note: definition of 'P' is not complete until the closing '}'
struct P {
 ^
1 error generated.
ASM generation compiler returned: 1
In file included from <source>:4:
In file included from /opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/functional:49:
In file included from /opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_function.h:60:
In file included from /opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/move.h:57:
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/type_traits:2936:63: error: calling '_S_get' with incomplete return type 'typename __invoke_result<A &>::type' (aka 'P')
      template<typename _Tp, typename = decltype(_S_conv<_Tp>(_S_get()))>
 ^~~~~~~~
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/std_function.h:349:4: note: in instantiation of template class 'std::__is_invocable_impl<std::__invoke_result<A &>, P, false>' requested here
        : __is_invocable_impl<_Res2, _Res>::type
 ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/std_function.h:353:34: note: in instantiation of template class 'std::function<P ()>::_Callable<A, A>' requested here
        using _Requires = __enable_if_t<_Cond::value, _Tp>;
 ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/std_function.h:434:33: note: in instantiation of template type alias '_Requires' requested here
 typename _Constraints = _Requires<_Callable<_Functor>>>
 ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/std_function.h:435:2: note: in instantiation of default argument for 'function<A>' required here
        function(_Functor&& __f)
 ^~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/type_traits:1297:4: note: while substituting deduced template arguments into function template 'function' [with _Functor = A, _Constraints = (no value)]
 __is_trivially_constructible(_Tp, _Tp&&)>>
 ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/type_traits:1303:14: note: (skipping 3 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
    : public __is_trivially_move_constructible_impl<_Tp>
 ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/variant:350:23: note: in instantiation of static data member 'std::__detail::__variant::_Traits<int, A>::_S_trivial_move_ctor' requested here
          _S_trivial_dtor && _S_trivial_move_ctor
 ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/variant:732:45: note: in instantiation of static data member 'std::__detail::__variant::_Traits<int, A>::_S_trivial_move_assign' requested here
      _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign, _Types...>;
 ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/variant:735:28: note: in instantiation of template type alias '_Move_assign_alias' requested here
    struct _Variant_base : _Move_assign_alias<_Types...>
 ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/variant:1337:15: note: in instantiation of template class 'std::__detail::__variant::_Variant_base<int, A>' requested here
    : private __detail::__variant::_Variant_base<_Types...>,
 ^
<source>:16:26: note: in instantiation of template class 'std::variant<int, A>' requested here
    std::variant<int, A> m_member;
 ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/type_traits:2930:37: note: '_S_get' declared here
      static typename _Result::type _S_get();
                                    ^
<source>:15:8: note: definition of 'P' is not complete until the closing '}'
struct P {
 ^
1 error generated.
Execution build compiler returned: 1
```


If I replace the implementation of `struct A` with the following implementation, clang can work properly:

```
struct A : std::function<P(void)> {
    // using std::function<P(void)>::function; // bad code
    
    A() = default;
    A(const A&) = default;
 A(A&&) = default;
    A(std::function<P(void)> f) : std::function<P(void)>(std::move(f)) {}

    // ...
};
```

Is this considered a bug in clang?
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsW19v4rgW_zTm5QgUHAjwwAMDZXekO9JoWu1r5CQH8NbYbOzQdh_uZ786zh8CbWl39uEyUqooQGwfO7_zx8c_nQpr5VYjztn4CxuveqJwO5PPV6v-f3qJyV7mLFixYPE7KmUYX0IqNFizR6MR8PmghNTgdtKycF32rO5RUF3lTx5KnaoiQ2DhclPo1EmjhWLh3VsdjiKXQrtTq79blxepg-8s_PLG4wWwcAHWZSxcsHBRz8HC5XfGp0cjM8ZnLLwDNqmGAwAUVurtJ0ZdNrdEML5mfA2DwaBa1WR1scLz5Z8voJm6eeel1I6QXtBi9_Ee9wnmJ4mvpEvtYC-kZnzK-Oxc-uXa6FmOrsg1BGci31Ra6_6wQxCJOSKkJkNvBQl93x-kwgxskaZo7aZQ6gWMBqEUbNOU8fW3-z-WcMTcSqMtuJ1wYIvDweQOWBS8Bj4KQOjsrK1GJgpIw2SnUbBz7mCp2b_g1mSJUW5g8i3j678ZX_-ZzB7-tr_hbzRqvGJ8-vkRfDaA9rv_bp7wiDnphN6reRmzgVQJvQVCnha3ZOGKmmE4HgQDDySfQY7-bd0OYWOUMk9kcZjnJqfVvO8zXzVspEKo_CKDTW725B3WFHmKpVGOGhnvdOdrc3CMrytV5X1yWpPT66y3adof8gEfBIyvlUzKR4yvn6dRHI36Suriub_VBePrpt9g8PpWzUnTMP7FX6cBbW9fjGa3v-BEOsv42joV12sf7Fi48Pb3a6x9b47o1zyenIzs_78693LA2OWCFhku-CyMCNaQ3Lp2CEiFUtI71SS-j7foGJ_Ak3Q7AtvsDwod1jGM5FFH-tRijxDHUh_NI8Y52kJRMF0A41ETwKkjyWN8Kh4FDf3O-IRCfBMeARzuD0o4ZOHyJPjhQP7f_CZPzzBVpcBpfB-nRh9ZuKSO4V35yC-egnJ11dsZsPHdf8u_m1FNY_TZudGH3mMpzIA2hMkCpAaprRPaSUH9KBDWmFFEtJaAbcJ3HEvr1ZKKRGEs9wdFQazV_J7K-BK-020jlPXxjk8gx78KtA4z2GGObbWBTwDeni3-gZaTKPpybg2NRm5fFePQK-Rf6KKd30BlmzUa8VIoRaCRCuoE5CPIy_wp_oF_FTJH6_0ijlGX4G9i0me8NLrZylWBXg-lmzR51K-A_8hDH4afxt-HJ6Gk8EpoQHoX01O0WRptKU5qV0HajCU4T3qK17RACpx31fUrwTmmTeAjNDPciEI5EPm22KN2sDE5wdky5bahyvxNO21682mDGY8YjyCON6f4fwrMl383A-f5Hjrks8llfH7aUWpii8Q66QpHDpphVqSYnUyzRtOC1M408Jw6tBGmDXP8xe_BNXjeKn2UeGWrjE-1gcrTZ5R8l9j6yOxyeZRCqRfaL8sTkSRT5tNqh_Ufkb9mN2vSFzoIA4oJwzMlMD61j_JwIPRDSI12-OzRhkSkjy4XlMF_gcIi9Dc16v2mra_kXjoWrgJwBixSHFFneQpNcigSJdNLZCn5O4e32QbLqHt7gDaH30U4piybfxhkrRNOppAJJ6A8Il8kHRk6IVX96zQB_XyoVNc-aldN9zWQFYw-UFzfAwFaozLvHFVoeUvYLYM_CSkcj8Y3An7JTV2HP_526hknwvpdsZkifng5oB0MBh_OQZGn3fcWE5O2ovzeOf3ZVKQNmn96DeSKuIr_KKf3KJe59msxF5DfMobDMKStc_ihtV8921yz9DZgF_Z-BW4f2HN5pBn_kfwz5PnyFfjnzNGQzt50zvrpl3-TsbxuSP-M67wpw3nFXdA-5S2otee3KIsMUyXeSkar4HlK9n9UB9_6SApn1EGbav7o711dk42fBYsMN1LLWskVDwLSUgdoaJZCO6k8c5kqYytWhk1WdH-P027WMCw5Hdiixlw4zCoOenH_rX5G09carTgdJBOBYUeB3saZraNAOwq0o0A7CvRWVNFRoB0F2lGgHQXaUaC3pYOOAu0o0I4C7SjQjgLtKNCOAu0o0I4CvUaB3j1jWviZk0Kq7CoHeqUo9-sGvkKOByVS9EukHAcpp21s19fRlvXRLApKEum8EvV8jC_x9kWtqdDwZPJHOOTmgLl6uV6t-q-qsKsy5Z8uxq4FJCLz9cktyc23RV0f7Wkrf6A6Myxq9xkjfYve7UndFk16flXaJ1DYlDI-g1hbIG3bjE83JanmsWxquN-t_T6rHH_LqL5aX8lPmbqVGZLjCkiKLQVFbxMsXPeyeZjNwpno4XwYTaazkIfjSW83Rz7iQbIJRDZNkjSZTDMxSUYJj8YYzTAZ9uScBzwMwmEU8GA8ngzGIUajKE02mAWbURKxUYB7IdVAqeN-YPJtT1pb4DwajkZhT4kElfX_pcC5xifwjYxzNl718jmN6SfF1rJRoKR19iTFSadw_pW6l_Zf2bf3ucZRfFn7OwboK9IvI3evyNX8oqhcul2RDFKzpyisjvVH_5CbPzGl4O1XbRlf-7f6XwAAAP__52y6Ag">