<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/57826>57826</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Rejecting captures of structured bindings in generic lambdas in C++20
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
PatrickAMoran
</td>
</tr>
</table>
<pre>
Building the following in `--std=c++20`
```C++
struct P { int a; int b; };
void repro() {
const auto [a, b] = P{1, 2};
(void)[&](const auto c) { return c - b; }(2);
}
```
Produces a failure with error message:
```
/home/pmoran/clang_testcase.cpp:13:41: error: reference to local binding 'b' declared in enclosing function 'main'
(void)[&](const auto c) { return c - b; }(2);
^
/home/pmoran/clang_testcase.cpp:13:45: note: in instantiation of function template specialization 'main()::(anonymous class)::operator()<int>' requested here
(void)[&](const auto c) { return c - b; }(2);
^
/home/pmoran/clang_testcase.cpp:12:18: note: 'b' declared here
const auto [a, b] = P{1, 2};
^
```
It is my understanding that the capturing structured bindings in lambdas may not have been standards conforming in earlier language versions, but that it _is_ standards-conforming in C++20. Commit 127bf44385424891eb04cff8e52d3f157fc2cb7c added support for capturing structured bindings in lambdas to fix #54300 and #52720. The error seems to persist here specifically because the lambda is a generic lambda. If you change the argument from `const auto c` to instead be the `const int c` that the lambda's call will resolve to, the error goes away.
I chased the source of the error as far as clang/lib/Sema/SemaExpr.cpp line 18831 where we see this comment:
```C++
// If we are instantiating a generic lambda call operator body,
// we do not want to capture new variables. What was captured
// during either a lambdas transformation or initial parsing
// should be used.
```
If you capture `b` by reference explicitly by name rather than using a default capture like so:
```c++
(void)[&b](const auto c) { return c - b; }(2);
```
Then you instead get this warning:
```
/home/pmoran/clang_testcase.cpp:13:12: warning: lambda capture 'b' is not required to be captured for this use [-Wunused-lambda-capture]
(void)[&b](const auto c) { return c - b; }(2);
^
```
So I think the issue resides in the detection of which values need to be captured by a lambda's body (even though here neither `b`'s type nor its value depend on the type parameter of the generic `operator()`).
Platform: I have only tested on linux x86_64,. but I don't think it's platform-specific
Versions Affected: I believe all versions up to and including the HEAD I pulled earlier today (2022-09-19).
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzFV9tu4zYQ_Rr5hbBhyTf5wQ-5LZqHAkG36D4GlDSy2aVElRc77tf3DCXH9maD7gVFA0eSKfJw5szMGbow1XFzG5SuVLsVfkeiNlqbA39TrUiW0_HY-SqZ3ZdJdotPNsVYMr1Ppjf8ED93_at-1HkbSi-eRLK6BYQXMpn1DwU_JKt73Pqpe6MqYamzJsnyJFvzkv6NEKVpHdYGb0SyuJVJdof1i3sBS8QT5qU8kl2iCQEUhgQSliTZEvMxdIFUDptgUx9sK0oxPluV5RmvPMHx0LWbw9d4fbKmCiU5IUUtlQ6WxEH5nSBrjRUNOSe3lMxuvgoBQz_sTEO4dY2xssVDqWW7ffbkfCkdTcquw-p0hss8xaUH5gdLNVlqSxJwSJtSalGoNoYvyVYF_kVFQLNUcQQxUxvHb-vQll6Zlqc1UmHT1X9CnPi2v2TxMJDzXWQsmIPWeCaX_VOwUbZeyeiaqc9uemo6LT0J11GppFZ_y2v382j1DX-yXLamPTYmOIHNnXt9ZTqy0oP6YfodMjmZPTDNlv4KMBE87xCR_5PLH-Mz40t-yeebBLp07Ecq8l0brwvi0QvlRHMUoa3IckAHOZI-alIpO1DFQ726BLZtyHrHWaBlU1QSEPLIzoid3JMoiFoRwaStHNtfG9sMykbSakVWMDMBtSr22Bjp4aJfwfebKy-elXs-o4yvUe5OojgR4s40Dean4LCez2f5Yp7N83VKxXRe1nVOi6ya1eliVZdZWaxKIasKXrjQdcZ6yK79djcRglq9IFyzxXw2nQoYF79kq2jJ76CsFyJH1MTpHXuH8HFA-4KoFaRDH8FSKYOjyHOPz7GQYkstWVUOY0B9rMXRBFHuwFg_XdptaAjKXlvTcK-4yvLllDfm-iQJN_olr5O4IfRzTkHuN0L6IVSwDHqKiyVn9J61juPiXx3bGtbegzxOLlX5ka1zII0nOhMsVBKScF4G7moZb7EkUBpaIeM_fKRGDreHl85yhQitWhJpns9ScYi0HYj5BJriZGrY87cKf9ULAYkPM3dgtuhSrRDlL0nu_T4pjijQm-H1FRRwKhNT_AAcJrhPGhItHcReWiULTQ7h-sS8HtjTfkJ1hVP1eUboWSgCec4sCIbjBB_01MJkBXu16KTlNnKF4nYm6BhbZFA1EV8v7iFvBjsxXnDci-NFK6OXTqtSec5HVLBsSIADNg3p0QK9p6uiWgbtX7G0-sxxfhuF8joK14pc_Ny54GvHAVRcG708pfuWfJ8oB2lbpu2do8B3Nb-o2BeI57QZqB3kG9tyhnB_Uiwh8LCg1zyIUhNt47IHJeNPoeX4jXu48TCRWXqnp_0cg__eDz4a8cgmtp9j7SrnArEUqIqiDvJgRZ7KU9M_7FS5Q_prNGRUwlufkVXyUmG4ttgt2hPDmbDd9drYDiUxpGmc7I8dXnAteNdvgt07guia3pY4AQWCvPVYO0jOqbgZ64tjBAOvr6RrOFbiwMLVx8F97LuYaVEUvj9nYDuoUngRL_nyeTmHOExir3qEKPB5zg-kKR_t7ga08Unw-03-GDqduKlrUAhliLsVhIaIDVmDTs1QhI6Z5P6icJAMr78Sfnm4uceaLmgNu07N1JtKRlqzaZaNp-txuj77OaJNulzOlmmGy6jazKr1bC1HHlVPm9_oT44m0IeQOWbxnTZ4rZruqhGPgtWbnfedi-c6lqktIhqKCSSb9V7vT7cxfnjwrvgaMwyt_8NilWfL0W6Tl8Wa0nRZVetqJYkyWteLPF2tV7Ks1vN8pCX4cptYDxlrb4TAM0pjpDZMwHSdrtN8tkqXk1lGS0rLxRLtZFEu6mQ-RatResJ2TIzdjuwmmlSErcNLjV7tzi9xIFVbpHXcDvgouZ2xmyfpQcPnm19ZOUbRgE104B_DQj7T">