On Mon, Jul 21, 2025 at 11:29:22AM -0400, Jason Merrill wrote:
> On 7/18/25 5:17 PM, Marek Polacek wrote:
> > On Thu, Jul 17, 2025 at 05:20:31PM -0400, Jason Merrill wrote:
> > > On 7/16/25 5:59 PM, Marek Polacek wrote:
> > > > On Mon, Jul 14, 2025 at 12:52:41PM -0400, Jason Merrill wrote:
> > > > > On 7/11/25 5:49 PM, Marek Polacek wrote:
> > > > > > On Thu, Jul 10, 2025 at 02:13:06PM -0400, Jason Merrill wrote:
> > > > > > > On 7/9/25 4:27 PM, Marek Polacek wrote:
> > > > > > > > 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.
> > > > > > > 
> > > > > > > I was hoping to avoid building more than one op().  But really, 
> > > > > > > why do you
> > > > > > > need an op() at all for building the proxies?  Could you use
> > > > > > > build_dummy_object instead of DECL_ARGUMENTS of some fake op()?
> > > > > > 
> > > > > > The problem is that we need operator() to be the var's DECL_CONTEXT
> > > > > > for is_capture_proxy:
> > > > > > 
> > > > > >      && LAMBDA_FUNCTION_P (DECL_CONTEXT (decl)));
> > > > > 
> > > > > Maybe we could set their DECL_CONTEXT to the closure type and adjust
> > > > > is_capture_proxy to handle that case as well?
> > > > 
> > > > Ah, now I recall why I had so much trouble when I tried that in GCC 15.
> > > > The problem is that the closure type is not complete at that point, and
> > > > that causes problems.  E.g., equal2 in lambda-scope3.C has
> > > > 
> > > >     return [t = t](const auto& obj) -> decltype(obj == t)
> > > > 
> > > > and the incomplete 't' in the decltype is problematic for 
> > > > cp_build_binary_op.
> > > 
> > > Hmm, problematic how?
> > 
> > decay_conversion has complete_type_or_maybe_complain.
> 
> But TREE_TYPE (t) isn't the closure, why would it be incomplete?

Its TREE_TYPE is "decltype (._anon_0->__t)" where _anon_0 is incomplete.
Presumably this type comes from lambda_proxy_type.

Marek

Reply via email to