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

    <tr>
        <th>Summary</th>
        <td>
            Poor compilation errors for NTTPs  in clang
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang
      </td>
    </tr>

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

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

<pre>
    Even though Clang was always known for great compiler error messages, it behaves poorly when NTTPs are used. Please see this Compiler Explorer link to compare the same error messages in GCC and CLANG: https://godbolt.org/z/bvfEa5jMr.

Typical issues are:
- printing `expr{{{}}}` instead of the actual type ( 'quantity<expr{{{}}}, double>')
- printing `{{{}}}` instead of just `{}` (`quantity<derived_unit<metre, per<second>>{{{}}}>`)

Longer example:

## GCC

```
error: conversion from 'quantity<mp_units::derived_unit<mp_units::si::metre, mp_units::si::second>(),[...]>' to non-scalar type 'quantity<mp_units::derived_unit<mp_units::si::metre, mp_units::per<mp_units::si::second> >(),[...]>' requested
    9 | quantity<si::metre / si::second> v1 = q;
      | 
```

## Clang

```
<source>:9:36: error: no viable conversion from 'quantity<{{{}}}, [...]>' to 'quantity<{{{}}}, [...]>'
 9 |   quantity<si::metre / si::second> v1 = q;
      | 
/opt/compiler-explorer/libs/mp-units/trunk/src/core/include/mp-units/quantity.h:124:3: note: candidate constructor not viable: no known conversion from 'quantity<expr{{{}}}, std::remove_cvref_t<double>>' (aka 'quantity<expr{{{}}}, double>') to 'const quantity<derived_unit<metre, per<second>>{{{}}}> &' for 1st argument
  124 |   quantity(const quantity&) = default;
      |   ^ ~~~~~~~~~~~~~~~
/opt/compiler-explorer/libs/mp-units/trunk/src/core/include/mp-units/quantity.h:125:3: note: candidate constructor not viable: no known conversion from 'quantity<expr{{{}}}, std::remove_cvref_t<double>>' (aka 'quantity<expr{{{}}}, double>') to 'quantity<derived_unit<metre, per<second>>{{{}}}> &&' for 1st argument
  125 |   quantity(quantity&&) = default;
      |   ^ ~~~~~~~~~~
/opt/compiler-explorer/libs/mp-units/trunk/src/core/include/mp-units/quantity.h:128:66: note: candidate template ignored: constraints not satisfied [with Q = quantity<expr{{{}}}, std::remove_cvref_t<double>>]
  128 |   constexpr explicit(!std::convertible_to<typename Q::rep, Rep>) quantity(const Q& q) :
      | ^
/opt/compiler-explorer/libs/mp-units/trunk/src/core/include/mp-units/quantity.h:127:12: note: because 'detail::QuantityConvertibleTo<mp_units::quantity<expr{{{}}}>, quantity<derived_unit<metre, per<second> >{{{}}}> >' evaluated to false
 127 |   template<detail::QuantityConvertibleTo<quantity> Q>
      | ^
/opt/compiler-explorer/libs/mp-units/trunk/src/core/include/mp-units/quantity.h:52:39: note: because 'implicitly_convertible(quantity<expr{{{}}}>::quantity_spec, quantity<derived_unit<metre, per<second> >{{{}}}>::quantity_spec)' evaluated to false
   52 |   Quantity<QFrom> && Quantity<QTo> && implicitly_convertible(QFrom::quantity_spec, QTo::quantity_spec) &&
 | ^
/opt/compiler-explorer/libs/mp-units/trunk/src/core/include/mp-units/quantity.h:136:22: note: explicit constructor is not a candidate
  136 |   constexpr explicit quantity(const Q& q) :
      | ^
/opt/compiler-explorer/libs/mp-units/trunk/src/core/include/mp-units/quantity.h:361:22: note: explicit constructor is not a candidate
  361 |   constexpr explicit quantity(Value&& v) : numerical_value_(std::forward<Value>(v))
      | ^
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzkWF1P4zgU_TXuyxVVYzdp89CHEtp5mR0NK7SvlZPctB4cO9hOGOZhf_vKTkoptLBi2ZmVFlUp4Pj63HuOjz-4tWKrEBckviTx1Yi3bqfNom5a-2OU6_JhsepQgdvpdruDTHK1hXtugct7_mDhVul7BZU2sDXIHRS6boREA2iMNlCjtXyLltAMhIMcd7xDC43WRj7A_Q4VfLm5-WqBG4TWYjmGrxK5RbCI4HbCQraPuPreSG3QgBTqFpwOY_l-bodgeY3PxgSh4FOWAVclZJ-XXz4RtoSdc40lbEnomtD1Vpe5lm6szZbQ9Q9C13lXrXj87TczJpMrMln2z5uHRhRcgrC2xQDWhwhNF9AYoZxQWyDJBL83hswu95-r4ZNMQCjrkJegq4CXF67lEtxDg0DoHAid3bVcOeEeCMvOhKEZlLrNJRK2InRGaHoKw5vjf2ute3wxNBI6J8nkCYASjeiw3LRKOMKyGp1BP3yDhrDMYqFV6UGw1YnR2MoH34Prn5-12npVfOd1Iw_VG56UEco8WUf_TSbDJ_wZyPUUFlp1aKzQCiqj62elq5sAOnDMls_zOGq0ov9-zO508yFbOvdZ0YzEl-PxmMRXPQ9ei0qrC1twyc2e038HVE_AG0DhNbAG71q0Dsu-rAAAKZBZBk_wHoEAQtfwcowuAsKu4I6wy0MkCJFO8ndEdfCRV8j2GHRriqB0tkwJW7LEk_-oAqWhEzyX-IYeTk-jEwy-o9uQd18--PgC0rVuHKHrvale4GCBhK6lyC2h67q56JVA18606pbQtTVF6OPlsxaqkG2Jx2_ugY53hC0jOvXV7WvqMMwwrkpRchdqa51pC6eNbx1KPtS_9_7Xy3_eyawr-4oYrHWHm6IzWG38hDh4XE8OoXN-y99rkQO3IRP4OIsDQhMPzi99kXXAzbatUbk9lRGdPpcFnT8D4SOkQQQlVryV7oQUAEi8gj-Pf36uPuL_gz4-WhlviCN-KY4jWbxDGT9XFHPClklyWhUO60b6X8RWaYPlsGpbZ7hQzgalWO6ErQSW3lTvhdvBdW-HH6iN-OpQ8PlQs4DDRwZfF1EIF1bK6DFkr1cncokbpwnL_Hqu_Pbyej9m4zH8jk3QUPpygl8TmsBdz-DyhbfHq5_L1Cw8nzKVY8FbGzYpJTouZJ_Y9dAvO1TgRr_YbbxNkK9K9g6rhfMzqp_o2HHZcoeln7MVlxaH4kbeBQK9e-mFUd9O7QBy5eld_WKyYk8TS89wJepesPJh80SkT53jNUqOyNvYBosPZunkCOmrvAHEdCDu-gDkem10fTDSoybP2mPD2YIMEU5mHEKcQrr37R7ar5iqYYtLj6bq3qSOVlrRWyg_WO6jz7HkrM_9t32KJdE_TZ4l0d9K_g8uWxwk1A3Zg2prNP6Qv_FixQ2h88clodLmnpuSsKzvGk5XXRB3er5s-xPNqFywMmUpH-EiStI4mqSzKB7tFlNe5lVFWVVM8jSvIl5F8SQqZhGfT9OE8ZFY0AllkzRKJ7PpnE7HUcEqNo2jNJmWcTRLyXSCNRdyLGVXj7XZjsINxSJJZtPpSPIcpQ0XO5QW4cRFKYmvRmbh37_I260l04kU1tlDBCecxMVXrc1wmcOd37uFg5cNO5r-xgaEghB01Bq5eHavItyuzceFrr1EZLf_umiM_oaFF1N_lULoOmD9KwAA__9wAKvJ">