<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - std::tuple<A&&> cannot be constructed from A&&, if A not defined (only forward declared)"
   href="https://bugs.llvm.org/show_bug.cgi?id=51378">51378</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>std::tuple<A&&> cannot be constructed from A&&, if A not defined (only forward declared)
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libc++
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>12.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>All Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>piotrwn1@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, mclow.lists@gmail.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>This code will not compile if A is only forward declared:

```

#include <utility>
#include <tuple>

class A{};
std::tuple<A&&> foo(A&& a) {
    return std::tuple<A&&>(std::move(a));
}

```

It looks like tuple constructors requires this to be true
`std::is_constructible<A &&, A>` - but IMO - this should be required only:
`std::is_constructible<A &&, A&&>` - so full definition of A shall not be
required in this case.

This is not compiling in all releases of clang/libc++.

Identical error I submitted to gcc-bugzilla:
<a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100667">https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100667</a> 
but there - it stop working in gcc11 (up to gcc10 it worked ok).

Compiler explorer link:<a href="https://godbolt.org/z/cd643zMn5">https://godbolt.org/z/cd643zMn5</a>
options: -std=c++20 --stdlib=libc++
and the errors:

n file included from <source>:1:
In file included from
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/utility:199:
In file included from
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/__tuple:15:
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/type_traits:2952:38:
error: incomplete type 'A' used in type trait expression
    : public integral_constant<bool, __is_constructible(_Tp, _Args...)>
                                     ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/__tuple:396:33: note:
in instantiation of template class 'std::is_constructible<A &&, A>' requested
here
    -> __all<typename enable_if<_Trait<_LArgs, _RArgs>::value,
bool>::type{true}...>;
                                ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/__tuple:401:36: note:
while substituting deduced template arguments into function template
'__do_test' [with _Trait = is_constructible, _LArgs = <A &&>, _RArgs = <A>]
  using __constructible = decltype(__do_test<is_constructible>(_ToArgs{},
_FromArgs{}));
                                   ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/__tuple:432:35: note:
in instantiation of template type alias '__constructible' requested here
    : public __tuple_sfinae_base::__constructible<
                                  ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:543:16: note:
in instantiation of template class 'std::__tuple_constructible<std::tuple<A>,
std::__tuple_types<A &&>, true, true>' requested here
               __tuple_constructible<
               ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:773:38: note:
in instantiation of function template specialization 'std::tuple<A
&&>::_CheckArgsConstructor<true>::__enable_implicit<A>' requested here
                         >::template __enable_implicit<_Up...>() ||
                                     ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:783:9: note:
while substituting prior template arguments into non-type template parameter
[with _Up = <A>, _PackIsTuple = false]
        tuple(_Up&&... __u)
        ^~~~~~~~~~~~~~~~~~~
<source>:6:28: note: while substituting deduced template arguments into
function template 'tuple' [with _Up = <A>, _PackIsTuple = (no value), $2 = (no
value)]
    return std::tuple<A&&>(std::move(a));
                           ^
<source>:4:7: note: forward declaration of 'A'
class A;
      ^
<source>:6:12: error: no matching conversion for functional-style cast from
'typename remove_reference<A &>::type' (aka 'A') to 'std::tuple<A &&>'
    return std::tuple<A&&>(std::move(a));
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:666:5: note:
candidate constructor not viable: cannot convert argument of incomplete type
'typename remove_reference<A &>::type' (aka 'A') to 'const std::tuple<A &&>'
for 1st argument
    tuple(tuple const&) = default;
    ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:667:5: note:
candidate constructor not viable: cannot convert argument of incomplete type
'typename remove_reference<A &>::type' (aka 'A') to 'std::tuple<A &&>' for 1st
argument
    tuple(tuple&&) = default;
    ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:701:5: note:
candidate template ignored: requirement '_CheckArgsConstructor<true,
void>::__enable_implicit()' was not satisfied [with _Dummy = true]
    tuple(const _Tp& ... __t)
_NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value))
    ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:719:14: note:
candidate template ignored: requirement '_CheckArgsConstructor<true,
void>::__enable_explicit()' was not satisfied [with _Dummy = true]
    explicit tuple(const _Tp& ... __t)
_NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value))
             ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:783:9: note:
candidate template ignored: requirement '_CheckArgsConstructor<true,
void>::__enable_implicit() || _CheckArgsConstructor<false,
void>::__enable_implicit()' was not satisfied [with _Up = <A>, _PackIsTuple =
false]
        tuple(_Up&&... __u)
        ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:816:9: note:
candidate template ignored: requirement '_CheckArgsConstructor<true,
void>::__enable_explicit() || _CheckArgsConstructor<false,
void>::__enable_implicit()' was not satisfied [with _Up = <A>]
        tuple(_Up&&... __u)
        ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:873:9: note:
candidate template ignored: substitution failure [with _Tuple = A]: no member
named '_EnableIfImpl' in 'std::_MetaBase<false>'
        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT,
_Tuple>::value))
        ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:878:9: note:
candidate template ignored: substitution failure [with _Tuple = A]: no member
named '_EnableIfImpl' in 'std::_MetaBase<false>'
        tuple(const _Tuple& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT,
const _Tuple&>::value))
        ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:883:9: note:
candidate template ignored: substitution failure [with _Tuple = A]: no member
named '_EnableIfImpl' in 'std::_MetaBase<false>'
        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT,
_Tuple>::value))
        ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:889:9: note:
candidate template ignored: substitution failure [with _Tuple = A]: no member
named '_EnableIfImpl' in 'std::_MetaBase<false>'
        tuple(const _Tuple& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT,
const _Tuple&>::value))
        ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:656:5: note:
candidate constructor template not viable: requires 0 arguments, but 1 was
provided
    tuple()
    ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:663:5: note:
candidate constructor template not viable: requires 0 arguments, but 1 was
provided
    tuple()
    ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:674:5: note:
candidate constructor template not viable: requires 2 arguments, but 1 was
provided
    tuple(_AllocArgT, _Alloc const& __a)
    ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:685:5: note:
candidate constructor template not viable: requires 2 arguments, but 1 was
provided
    tuple(_AllocArgT, _Alloc const& __a)
    ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:737:7: note:
candidate constructor template not viable: requires 3 arguments, but 1 was
provided
      tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
      ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:757:7: note:
candidate constructor template not viable: requires 3 arguments, but 1 was
provided
      tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
      ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:843:9: note:
candidate constructor template not viable: requires at least 2 arguments, but 1
was provided
        tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
        ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:863:9: note:
candidate constructor template not viable: requires at least 2 arguments, but 1
was provided
        tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
        ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:902:9: note:
candidate constructor template not viable: requires 3 arguments, but 1 was
provided
        tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
        ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:916:9: note:
candidate constructor template not viable: requires 3 arguments, but 1 was
provided
        tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
        ^
2 errors generated.
ASM generation compiler returned: 1
In file included from <source>:1:
In file included from
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/utility:199:
In file included from
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/__tuple:15:
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/type_traits:2952:38:
error: incomplete type 'A' used in type trait expression
    : public integral_constant<bool, __is_constructible(_Tp, _Args...)>
                                     ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/__tuple:396:33: note:
in instantiation of template class 'std::is_constructible<A &&, A>' requested
here
    -> __all<typename enable_if<_Trait<_LArgs, _RArgs>::value,
bool>::type{true}...>;
                                ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/__tuple:401:36: note:
while substituting deduced template arguments into function template
'__do_test' [with _Trait = is_constructible, _LArgs = <A &&>, _RArgs = <A>]
  using __constructible = decltype(__do_test<is_constructible>(_ToArgs{},
_FromArgs{}));
                                   ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/__tuple:432:35: note:
in instantiation of template type alias '__constructible' requested here
    : public __tuple_sfinae_base::__constructible<
                                  ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:543:16: note:
in instantiation of template class 'std::__tuple_constructible<std::tuple<A>,
std::__tuple_types<A &&>, true, true>' requested here
               __tuple_constructible<
               ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:773:38: note:
in instantiation of function template specialization 'std::tuple<A
&&>::_CheckArgsConstructor<true>::__enable_implicit<A>' requested here
                         >::template __enable_implicit<_Up...>() ||
                                     ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:783:9: note:
while substituting prior template arguments into non-type template parameter
[with _Up = <A>, _PackIsTuple = false]
        tuple(_Up&&... __u)
        ^~~~~~~~~~~~~~~~~~~
<source>:6:28: note: while substituting deduced template arguments into
function template 'tuple' [with _Up = <A>, _PackIsTuple = (no value), $2 = (no
value)]
    return std::tuple<A&&>(std::move(a));
                           ^
<source>:4:7: note: forward declaration of 'A'
class A;
      ^
<source>:6:12: error: no matching conversion for functional-style cast from
'typename remove_reference<A &>::type' (aka 'A') to 'std::tuple<A &&>'
    return std::tuple<A&&>(std::move(a));
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:666:5: note:
candidate constructor not viable: cannot convert argument of incomplete type
'typename remove_reference<A &>::type' (aka 'A') to 'const std::tuple<A &&>'
for 1st argument
    tuple(tuple const&) = default;
    ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:667:5: note:
candidate constructor not viable: cannot convert argument of incomplete type
'typename remove_reference<A &>::type' (aka 'A') to 'std::tuple<A &&>' for 1st
argument
    tuple(tuple&&) = default;
    ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:701:5: note:
candidate template ignored: requirement '_CheckArgsConstructor<true,
void>::__enable_implicit()' was not satisfied [with _Dummy = true]
    tuple(const _Tp& ... __t)
_NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value))
    ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:719:14: note:
candidate template ignored: requirement '_CheckArgsConstructor<true,
void>::__enable_explicit()' was not satisfied [with _Dummy = true]
    explicit tuple(const _Tp& ... __t)
_NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value))
             ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:783:9: note:
candidate template ignored: requirement '_CheckArgsConstructor<true,
void>::__enable_implicit() || _CheckArgsConstructor<false,
void>::__enable_implicit()' was not satisfied [with _Up = <A>, _PackIsTuple =
false]
        tuple(_Up&&... __u)
        ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:816:9: note:
candidate template ignored: requirement '_CheckArgsConstructor<true,
void>::__enable_explicit() || _CheckArgsConstructor<false,
void>::__enable_implicit()' was not satisfied [with _Up = <A>]
        tuple(_Up&&... __u)
        ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:873:9: note:
candidate template ignored: substitution failure [with _Tuple = A]: no member
named '_EnableIfImpl' in 'std::_MetaBase<false>'
        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT,
_Tuple>::value))
        ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:878:9: note:
candidate template ignored: substitution failure [with _Tuple = A]: no member
named '_EnableIfImpl' in 'std::_MetaBase<false>'
        tuple(const _Tuple& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT,
const _Tuple&>::value))
        ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:883:9: note:
candidate template ignored: substitution failure [with _Tuple = A]: no member
named '_EnableIfImpl' in 'std::_MetaBase<false>'
        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT,
_Tuple>::value))
        ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:889:9: note:
candidate template ignored: substitution failure [with _Tuple = A]: no member
named '_EnableIfImpl' in 'std::_MetaBase<false>'
        tuple(const _Tuple& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT,
const _Tuple&>::value))
        ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:656:5: note:
candidate constructor template not viable: requires 0 arguments, but 1 was
provided
    tuple()
    ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:663:5: note:
candidate constructor template not viable: requires 0 arguments, but 1 was
provided
    tuple()
    ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:674:5: note:
candidate constructor template not viable: requires 2 arguments, but 1 was
provided
    tuple(_AllocArgT, _Alloc const& __a)
    ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:685:5: note:
candidate constructor template not viable: requires 2 arguments, but 1 was
provided
    tuple(_AllocArgT, _Alloc const& __a)
    ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:737:7: note:
candidate constructor template not viable: requires 3 arguments, but 1 was
provided
      tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
      ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:757:7: note:
candidate constructor template not viable: requires 3 arguments, but 1 was
provided
      tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
      ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:843:9: note:
candidate constructor template not viable: requires at least 2 arguments, but 1
was provided
        tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
        ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:863:9: note:
candidate constructor template not viable: requires at least 2 arguments, but 1
was provided
        tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
        ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:902:9: note:
candidate constructor template not viable: requires 3 arguments, but 1 was
provided
        tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
        ^
/opt/compiler-explorer/clang-12.0.1/bin/../include/c++/v1/tuple:916:9: note:
candidate constructor template not viable: requires 3 arguments, but 1 was
provided
        tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
        ^
2 errors generated.
Execution build compiler returned: 1</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>