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

    <tr>
        <th>Summary</th>
        <td>
            Trivially Default Constructible with `requires` + Structure Wrapping
        </td>
    </tr>

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

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

    <tr>
      <th>Reporter</th>
      <td>
          geometrian
      </td>
    </tr>
</table>

<pre>
    Consider the following semi-minimal example:
```cpp
#include <type_traits>

template<int n>
struct Foo {
        constexpr Foo() = default;

        template<class... Ts>
        Foo(Ts... vals) requires(sizeof...(Ts)==n) {}
};

struct Bar {
        Foo<4> foo;
};

static_assert(std::is_trivially_default_constructible_v< Foo<4> >); //Fine
static_assert(std::is_trivially_default_constructible_v< Bar    >); //Fails???
```
The first `static_assert` passes, indicating that `Foo<4>` is trivially default constructible. However, we now wrap `Foo<4>` in a class `Bar` which does nothing, and suddenly the type is no longer trivially default constructible and the second `static_assert` fails:

    <source>:16:1: error: static assertion failed due to requirement 'std::is_trivially_default_constructible_v<Bar>'
    static_assert(std::is_trivially_default_constructible_v< Bar    >);
    ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1 error generated.
    Compiler returned: 1

I believe this is an error. We can verify that `Foo<4>` is indeed trivially default-constructible per [the definition](https://en.cppreference.com/w/cpp/language/default_constructor#Trivial_default_constructor), and of course by the `static_assert` passing. Even if `Foo<4>` didn't fully constrain the constructors, the non-`template`d `default`ed constructor should be selected preferentially. Next, wrapping `Foo<4>` in `Bar` should do nothing; if anything it should ensure that *only* the default constructor is accessible. And finally, GCC, MSVC, and even Intel Compiler (now based on LLVM) accept this code without complaint.

The tested version:

    clang version 16.0.0 (https://github.com/llvm/llvm-project.git 437ccf5af9c2aec915a68a164a95d506fbac2324)

Note that this is a regression. E.g. Clang 15 accepts the code.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzNVk2PozgQ_TXkYjXiI0BzyCGhO7sjzcxlWjPHljFF4hWxWdsk3fvrt8qQhCg9K400h41IAJdd9Vz16jm1bt5XlVZWNmCY2wNrddfpk1Q7ZuEgHw5SyQPvGLzxQ99BkK6D6CmI1kEejZfo-2kkSaUS3dAAC9LKvffw6gyXzgbp8zTD_zpAR9yhq0oqx9TFbJ0ZhGNbrVlQbM5LSoHoHLz1hixB8hgkJQZ4Yg20fOhckG7m3nHBLIDouLVhGLKXOYpydPTiLUfeWXJp4O9BGsDnRyv_Ad2i0U9CI4bDS_nIiKx4mjzhw230aQsbbm62QPHSaokQML36uuaD9dxJ8YqgwThC4hrKeLqWFpMpj5J33fvrtPNXnxkKKOsOXo8Ygs0i0YYJ-oYFyRavrVTwm6LQ_vBzF4FLzGW6na5bnoyvL8QwaaxjOHSLI49YT4-Y8IpJ1UiBVqSh23M_-7o1miotu0A9U4HdQA3Zn_oERzDk7wRM6RM7Gd5_4EsxzjxVyIabo8HTXoo9azRYXOn2iIT8cNUwOzQNKAxL7UI8JzBKs06rHTXRf8PyLmilBRxvPsxDOyZyPafGmPDK6sEIIODpOs7pB78MjNGGHkZXbHQltfKuoGHNgFD1meQHwMYLkuJXC0-poZoXV0i_nUuz3WbPbP4Jiuf_6XWBHI-VYDtQYFCCmvBqq_Shx1oYLIIbjALKE4vnJf7EaugkUhb5gZTCi6vRYch-ABP4hnSW7fvPewL7BrDcdxx8uOVgjzCCbEM0xAko8cSVIHvCAu6d6z33fEuDClHgDbRgQAkIhT7g6Am_pPvJtuNqN_Ad4ONdjZGRSfoyIrlnAFnLc0vpFptkMBZYPbbVz9QB2zBkz0dQTLb3CWhkgyJdONYOtPcxFsf2JpezyF5iaExp9YALLydGHvmGPB8teYS5nK1jdq-HrsEyYfd2ILDA7Jwc5_Mdsq_w5rzioNT0pF8fyc1VZiaPjb6oDMop7o2rd__KpDvPAWUHA1Ptk7VGCcIbm4p4qzSIlegjBGDOvBiuMc1YaQJJ8P6oKrp9-fa9OhcBKK2flIPuylUkBOlmzS1uFeXk8-fvX-gYJM-9G3kqNB75J-kQJSGgVOLBHs6ZTbLvwFK-kMGWyHavboLIdLazOA-jMGJ3jNxhoKGeiNh1x_PtoTf6LyxJiBPYMi2EaDPeliLhIMo44_kjj_MlL7Mmi_K25iJJkyVRcIbiq3ZTfi8NiN26M5RErZB4IbKv8jDjbMqBncjVQLiAVZzn5TJOl0W2aFZpU6YlXzjpOli9XFryaSpWddOSlEDixeV_SE6b37BvfgoV_sfEqMVgutWvJQVfpbUDna3brEyifLFfcVE8Jo-ibBtelGIJRSvqOuNQ44REtOWi4yhHdoU6ESSJghPzLvAZhWIhV0mUJHGcZEmcFVkWllGbJo9pHYu8SdEULCM44OETEo5Qm93CrDykethZNHbSOns1Um_vFIAPh_75gHwyqx3oA6CacbXw0Vce_b9YuFzF">