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

    <tr>
        <th>Summary</th>
        <td>
            `requires` expression failure could provide more helpful diagnostics
        </td>
    </tr>

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

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

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

<pre>
    I initially had such an implementation of the concept:

```cpp
template<typename Q1, typename Q2>
concept A =
  Quantity<Q1> && Quantity<Q2> &&
  requires { common_reference(Q1::reference, Q2::reference); };
};
```

The above produces the following error message on failure:

```
note: because 'A<quantity<hertz{{{{{}}}}}, int>, quantity<struct becquerel{{{{{}}}}}, int> >' evaluated to false
   511 |   requires A<quantity<R1, Rep1>, quantity<R2, Rep2>>
       |            ^
note: because 'common_reference(Q1::reference, Q2::reference)' would be invalid: no matching function for call to 'common_reference'
   113 |   requires { common_reference(Q1::reference, Q2::reference); } &&
       | ^
```

This log is not useful because the user does not know what `Q1::reference` and `Q2::reference` are.

So, I added the following:

```cpp
template<auto R1, auto R2>
concept HaveCommonReference = requires { common_reference(R1, R2); };

template<typename Q1, typename Q2>
concept A =
  Quantity<Q1> && Quantity<Q2> &&
  HaveCommonReference<Q1::reference, Q2::reference>
};
```

but it still provides the following:

```
note: because 'A<quantity<hertz{{{{{}}}}}, int>, quantity<struct becquerel{{{{{}}}}}, int> >' evaluated to false
   512 | requires A<quantity<R1, Rep1>, quantity<R2, Rep2>>
       | ^
note: because 'HaveCommonReference<quantity<hertz{{{{{}}}}}, int>::reference, quantity<struct becquerel{{{{{}}}}}, int>::reference>' evaluated to false
   115 |   HaveCommonReference<Q1::reference, Q2::reference> &&
       |   ^
 ../../src/core/include/mp-units/framework/quantity.h:106:42: note: because 'common_reference(R1, R2)' would be invalid: no matching function for call to 'common_reference'
   106 | concept HaveCommonReference = requires { common_reference(R1, R2); };
       | ^
```

It would be great to get better information at this level by saying what `R1` and `R2` are.

As a workaround, I had to go even deeper with such a change:

```cpp
template<auto R1, auto R2>
concept HaveCommonReferenceImpl = requires { common_reference(R1, R2); };

template<auto R1, auto R2>
concept HaveCommonReference = HaveCommonReferenceImpl<R1, R2>;
```

and finally, I have this error message

```
note: because 'A<quantity<hertz{{{{{}}}}}, int>, quantity<struct becquerel{{{{{}}}}}, int> >' evaluated to false
   511 | requires A<quantity<R1, Rep1>, quantity<R2, Rep2>>
       | ^
note: because 'HaveCommonReference<quantity<hertz{{{{{}}}}}, int>::reference, quantity<struct becquerel{{{{{}}}}}, int>::reference>' evaluated to false
   114 |   HaveCommonReference<Q1::reference, Q2::reference> &&
       |   ^
note: because 'HaveCommonReferenceImpl<mp_units::si::hertz{{{{{}}}}}, struct becquerel{{{{{}}}}}>' evaluated to false
   106 | concept HaveCommonReference = HaveCommonReferenceImpl<R1, R2>;
       | ^
note: because 'common_reference(R1, R2)' would be invalid: no matching function for call to 'common_reference'
   103 | concept HaveCommonReferenceImpl = requires { common_reference(R1, R2); };
 |                                              ^
```

However, we probably agree this is not what we want the users to write to get meaningful diagnostics?
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWEuTmzgQ_jXypSsuEAbbBw4eT1yZY2b3nhLQgDZCInqYdX79lniMPZ6Xs_FsqlJLUTZI0Or-uvV9EswYXknElMQ3JL6dMWdrpdOmdeb7LFPFIb0DLrnlTIgD1KwA4_IamATetAIblJZZriSoEmyNkCuZY2tJtCHBLQmm3yQYzrxthxaLTSuYRRJt7aFFyRqEzyGhWzjeUhJ9HJ4ercIGSHQ7NAF8dkxabg8k2n4OSfQRCE0ITR6102P79JrGb45rNECWN5CrplHyi8YSNcocCV15WxsSbU7atr0vZ41rEt0AWd6S6GYM8vR6CvgUhT9rBJapPUKrVeFyND1kpRJCdVxWgForDQ0awyoEJaFkXDiNL6E53ErlYdxAhjlzBoHQ5YZE229HGGrU9jtZ3jw-bx-ddAtcWo843cLJu8Zql1tv_JtDjeJSM9CbWgLumXDMYgFWQcmEwSkREIchkOUWTnJy5vh9XxH32IZPHbunY19fJlOlwHAMZh8OEn98EaufKgG6hE45UUCGwOWeCV5481JBw2xe-6SWTub9DCmVhpwJ4YF4dtzlQwhhGJ0jc6VqPZsMD2A9IPRC5XIDQlXADUhlwRksnXhA0VexM6ihUDg88FWqDrqaWSBJ8NTHJAAmi77viau-T-P8dPg_lI_qDlhR-Do6nTM_QjTMWQVDSQ2XTwnmE9vjtkf5fnLIU86baRgLlT5HC7-Y754JabRwQd1MDr3JbZmzwC0Yy4Xw9LbnxTm9_bYsRvsZ9C4c9hpxPZ_Yfw3Y03K4An7P1NPraIZhPDLfT9btS0R3IgYwnxO663-Mzgnd5UojoTsuc-EKf9W0H5zk1hC6KzVrsFP6K6G7CZh5TaJNGCQk2izowPuXyMspWbyXgARJH-078trF4nFnjyFWGpn1_lfoq8la1MBlqXQzrCJ9Z681uEcB2QEMO3gMJim5D0-0454-JxYbAwx8ophWThaDcviFqx9VAe5RQoHYooaO23pcz0JeM1m9uNK6npzcNa24uqT8hLK94OKRuAZqeo37fTpKLv0OYUJ7j0MeH61of0_2D_9n_yuy_-I_Y__LMB3nQtN-GYSgH8nw4f9CiH8QvrdRupDcf2xqX1h3v0rPordCvgaxnu8b3z5el75PqsM9aj9e1-_6M5aJA7BK40iQ44aq17cOoWPSPmynjAem09zipJgNMsll5fdeBWeVVMby3JBoNyvSqFhHazbDNFyG6ygK4mQ1q1OkwbIMlmtW0LhcL1ZFRoMEs1WY0CJfF8GMpzSgiyChcRgv1nQ1j8OixNUqpitEjJIFWQTYMC7mQuybudLVjBvjMF0nSRLMBMtQmP7rEaUSO-g7CaUkvp3p1L_zIXOVIYtAcGPN0YrlVmBKkmDKlxdz_LvVaAw_fvuAvC-ncUsBjdIINYr2DIOZ0yKtrW37KUp3hO4qbmuXzXPVELrzw45_H1qt_sLc-pWed9av7oZg9in9JwAA__9ud56o">