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

Reply via email to