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

    <tr>
        <th>Summary</th>
        <td>
            Incorrect Clang compilation error in non-taken if-constexpr branch within template lambda
        </td>
    </tr>

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

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

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

<pre>
    Godbolt: https://godbolt.org/z/WGWWozG1q

The scenario is fairly strange to reproduce.  It's code to conditionally wrap a callable with a mutable or a const lambda.  The `if constexpr` branch that isn't taken causes the compilation to fail.

Simplified code:

```c++
#include <cstdio>
#include <iostream>
#include <type_traits>
#include <utility>

struct ConstWrap
{};
struct MutableWrap
{};

auto lambdaWrap(auto callable) -> decltype(auto)
{
    const auto decorator = [&callable]<typename WrapType>() {
        if constexpr (std::is_same_v<ConstWrap, WrapType>) {
            return [capturedCallable = std::move(callable)]() {
                std::puts("ConstWrap");
 capturedCallable();
            };
        } else {
 return [capturedCallable = std::move(callable)]() mutable {
 std::puts("MutableWrap");
                capturedCallable();
 };
        }
    };
    return decorator.template operator()<MutableWrap>();
}

int main()
{
    auto decorated =
 lambdaWrap([counter = 0]() mutable { std::cout << "Counter: " << ++counter << "\n"; });
    decorated();
    return 0;
}
```

This fails with

```
<source>:17:17: error: no matching function for call to object of type 'const typename std::remove_reference<(lambda at <source>:32:20) &>::type' (aka 'const (lambda at <source>:32:20)')
   17 | capturedCallable();
      | ^~~~~~~~~~~~~~~~
<source>:15:63: note: while substituting into a lambda expression here
   15 |             return [capturedCallable = std::move(callable)]() {
      | ^
<source>:13:61: note: while substituting into a lambda expression here
   13 |     const auto decorator = [&callable]<typename WrapType>() {
      | ^
<source>:32:9: note: in instantiation of function template specialization 'lambdaWrap<(lambda at <source>:32:20)>' requested here
   32 |         lambdaWrap([counter = 0]() mutable { std::cout << "Counter: " << ++counter << "\n"; });
      |         ^
<source>:32:20: note: candidate function not viable: 'this' argument has type 'const typename std::remove_reference<(lambda at <source>:32:20) &>::type' (aka 'const (lambda at <source>:32:20)'), but method is not marked const
   32 | lambdaWrap([counter = 0]() mutable { std::cout << "Counter: " << ++counter << "\n"; });
      |                    ^
1 error generated.
Compiler returned: 1
```

on Clang 18.1.0 and on trunk (same error).  This works if the `decorator` lambda is not within a templated function (e.g., move it into `main()` and it works).  My current workaround is to move the `if constexpr` outside of the `decorator`.

GCC 10.4 is capable of compiling this example.

Perhaps this is related to #113792.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzUV01v4zgS_TX0pRBDImPLPvjgKB-YwwAL7AA5BjRVtriRSA1ZSjp92N--KEq25bR70YduoEcw4phFFV-9Kj4WdYz24BA3YnEnFvcz3VPtw6a1r7hDRw1-5IvZzlcfmydf7XxDQm2hJuqiUFshH4V8PAyGuQ8HIR-_Cvn4_PT87L8-5X-LbCuy7V81QjTodLAebIS9tqH5gEhBuwMCeQjYBV_1BucAf5CQRQTjq2Qy3lWWrHe6aT7gPegONBjdNHrXILxbqkFD21P66QMbvYsEjW53lZ4D8Opimdn9YMAvXRDLDHZBO1MD1ZrARidkQUD6FR0Y3UeMQDWC8W1nG83LM5a9ts18iOnftu0au7dYJaRMRhoXy2z4GCHv-JNthVTWmaavEIQqTaTKeqEevrFYHymgbq_Z6KPDFwraUrxm7sk2lj5GU7aNFHpDUHLAz0F3PFrcieJeqLuz-c-BtSsTRLbVPfmRxDRBrtLIkXkh13Aj1ANUaBpGN04Qcj36yrYAMCYjvVqh8UGTDyDUPXC9yeXJ3eJ-jNLpFoFX_IudqgchV7zW2SM_02SCkKtIFWdAbW18ibrFlzehynP0srz0-NkdPwGpD45hGd1RH7Aqj0XGcE8rtP6NY53wwNivgTw-p1e7nmKaKSfQJHtIpMPnhQevo3HynNI0GQBsIh4B_IxYjltqdHkliGn5TMP49PzfqK6FMv66MI0RnUpoTth2jSYE32EaObotp7CO5TNWdfItsq11BK22bjRO63VaqVgxXWy42AdMq-8d4VDI2VXOzoQZ3xPvUaFKSKlPr7KMCinPBhaLs9vjbLEoHX-pu8THlOMTyM9lMnKVXQR9lKWjIg8y3MSkoJ-ki_9XZfR9MGm_qG1eHP8AhuATeueh1WRq6w6w751JIrn3IUkEq6Xf_QcNgd8D72sQshjE4LTLTxQF5Ep8CbjHgI4XLYVcDaSDTuxN0Sgp1FZmacfJ5TAm1HZQoYL1QL_q83o_5krIYqgFAMgLEEX5A_uRZ4nFw38vnyv8LYTaLtVAG_FpAe-1bRBiv4tkqSdm0TryoMdiA9Y2jJFZrTHgiGyR1vyVwjXGdCUIxr_Mf0IQ6hTErzgevhtASvZ6it86sC6SdmSHQ97vz7V8kpjYobG6sV-HOUIWEz340VJNWAsI-HePkaXlzIeSF0n9HcUGLhB-n12ZTek12lW2YgpPpDpP8GZTThOogmobmRgdDn2LjqDW8Z8kGLKEXU_QItW-4u6WI2x1eE2doYt0kePfP7fTPiOlOR8kHw7oMJ033AGXqTHGMKoPMkTIvz1ovIOy0e4A-WqezzPQrgLeWqF3r6lx47QOR4pcp2bdRnj34TVyj0dD635SBu7bx8yMRPPpZR3o02atzqUm5ArnhzlniKsFLA3iJJbZ5PBfDqAsDcsOMP78ANOHwOXIozr43qXkkh980fVLhe8p2grTmfct9vHq8FSWkGfzW_ZndDdcXPbjXYMllLcE4Bfddg2O7_wLQ627OJhshIBDsByOVHmuirWcz6qNqtZqrWe4yYvbXGZZoeSs3qyyVa5xleW3uFqpZbXLb43SxizlWuZyv5jZjczkIlPZIl8tZC7nu0WxNItVplSeG4OZuM2w5dtP07y1fNOb2Rh73ORyvc7lrNE7bGK6Q0ppOOGp5O5nYcMv3Oz6QxS3WWMjxbMLstTg5g9nfAjcKQyVMr1zDZVnWTbczXA7s_ubc-s_XuLGKjgJ9lAjsz40m09XVUt1v5sb3wr5yDjGr5sueG5WhHxMcUUhH8fQ3jbyfwEAAP__8vOErA">