On Tue, Jul 08, 2025 at 12:15:03PM -0400, Jason Merrill wrote: > On 7/7/25 4:52 PM, Marek Polacek wrote: > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? > > > > -- >8 -- > > This patch is an attempt to implement P2036R3 along with P2579R0, fixing > > build breakages caused by P2036R3. > > > > The simplest example is: > > > > auto counter1 = [j=0]() mutable -> decltype(j) { > > return j++; > > }; > > > > which currently doesn't compile because the 'j' in the capture isn't > > visible in the trailing return type. With these proposals, the 'j' > > will be in a lambda scope which spans the trailing return type, so > > this test will compile. > > > > This oughtn't be difficult but decltype and other issues made this patch > > much more challenging. > > > > We have to push the explicit captures before going into > > _lambda_declarator_opt > > because that is what parses the trailing return type. Yet we can't build > > any captures until after _lambda_body -> start_lambda_function which > > creates the lambda's operator(), without which we can't build a proxy, > > but _lambda_body happens only after parsing the declarator. This patch > > works around it by creating a fake operator() in make_dummy_lambda_op. > > I was thinking that we could build the real operator() earlier, before the > trailing return type, so that it's there for the above uses, and then splice > in the trailing return type to the already-built function declaration, > perhaps with apply_deduced_return_type.
Ah, I see what you mean. But it's not just the return type that we don't have at the point where we have to have the operator(): it's also tx_qual, exception_spec, std_attrs, and trailing_requires_clause. Especially the requires clause seems to be awkward to set post grokmethod; it seems I'd have to replicate the flag_concepts block in grokfndecl? Maybe I could add (by that I mean add it to the lambda via finish_member_declaration) a bare bones operator() for the purposes of parsing the return type/noexcept/requires, then after parsing them construct a real operator(), then find a slot of the bare bones op(), and replace it with the complete one. I'm not sure if that makes sense to do though. Marek