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

    <tr>
        <th>Summary</th>
        <td>
            [clang] constraints on constructors appear to be evaluated on class synthesis rather than on use
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            c++
      </td>
    </tr>

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

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

<pre>
    I was confused about what was happening with https://discourse.llvm.org/t/detect-if-type-is-complete-not-forward-decl/87107

It looks like we're trying to evaluate `requires` constraints on constructor methods during class synthesis rather than on use of the constructor, but I believe evaluation of these constraints should not occur until synthesis of the constructor.

https://godbolt.org/z/eM5dx99sY

```c++
#include <type_traits>

struct Dummy;
template<class T> struct MyTemplate {
        T*p;
        MyTemplate() 
                requires (std::is_default_constructible_v<T>)
                { }
};

class MyTest {
        MyTemplate<struct Dummy> data;
public:
        MyTest();
        void someFn() { }
};

MyTest test;

int main() {
        test.someFn();
}

struct Dummy { int a; };
MyTest::MyTest() { }
```

This happens for all the constructors, even those that are not used - a minor modification: https://godbolt.org/z/YTK9c6adj - shows that the requires clause is evaluated for all constructors, even those that are not used in the TU:

```c++
#include <type_traits>

struct Dummy;
template<class T> struct MyTemplate {
        T*p;
    MyTemplate();
        MyTemplate(float f) 
                requires (std::is_default_constructible_v<T>)
                { }
};

class MyTest {
        MyTemplate<struct Dummy> data;
public:
        MyTest();
        void someFn() { }
};

MyTest test;

int main() {
        test.someFn();
}

struct Dummy {  int a; };
MyTest::MyTest() { }
```

</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzsVk2P4zYM_TXKhXDgyHEcH3zIfAQYFHtLD3sayBYda1a2UpFKmv76QnaSyUwXXRTtoYcFDASWycfHjydGEZn9gFiJ_EHkTzMVuHO-cm9dGHhWO32uXuCkCBo3tIFQg6pdYDh1isfzTh0OOJhhDyfDHXTMBxLZRsitkFttqHHBE86tPfZz5_dCbjl-QMaGE9MmfD5gYihpXH-wyJgMjpPW-ZPyOtHYWCG362KRFiLdiHTzwmCd-0ZgzTeEEwpZeAT258iAHeBR2aAYQaxSj78F45HEKo30ib0yAxO44fIaGnYeeuTOaQIdfARprCICOg_cIRkCr7hDD9ypIXoGQnAtcIf3IEI-Qh0YXqBGa_CIVyLGDRdzwg8kqHPBahgcg2ua4CEMbOxd3L8GmU8l-FjivdO1s3yp7R9CbvFLrn8vS_o6mYtVOj2NkA_xSTdCZmZobNAIInuMHXiNtJhE9jw5TSHhKfT9WWTRh7E_WMUossepQjuRPcPF7st5d_kMohgjpOVOyM1h8hVp-W4h5FrIEqZjkZbXLoGQa2IdE8s2hl41tipYfr0VwNQWX48ie4yRhSxvCKJ4AFE8xffi6RpxM7GMcYnfWd3xyB4_ZvkMWrGa_A-htqaJXG5exBPzW0pHZzSQ63E7XHP6LpELBY4I1zMzMPTK3DlOmNFofo958ZhAP_ZlDBeBIme4RbxwHct4z_ue3XUkJtBdZ646JmidB2Xt59mjOOF4xAG4c4RRDgzK4zjA472QgILeDFFQTpvWNOPwi2wDPxrYr7tfymal9BskURYnmtAjg9twNFZF5Rm6KVzfqP4jmmYYgXe_Xpv7fxAIAMBnhXxfOq11iqH9qaD_TEH_XkIzXWW6zEo1w2pR5ItFni2X-ayrGsyyZZ1naYtF1i6LcqkzpeV6JYt2ka4WM1PJVObpSq5llqXLfF7WqpWLVhbrhczLuhbLFHtl7G1_zgxRwGqxXMnlamZVjZbG3S3ldXyljIvcV9ElqcOexDK1hpjeQdiwHVd-Y9WwF_nT3-xHgngzKB-3a4138otmP9yVs-Bt9ekCMNyFet64XshtpHT5SQ7evWET_x6MSZKQ20uex0r-GQAA__8V4rT3">