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