https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122884

--- Comment #5 from Jason Merrill <jason at gcc dot gnu.org> ---
So currently we build early capture proxies to refer to a dummy op().  When
substituting the noexcept or requires, local_specializations doesn't have a
binding for the capture proxies (because they aren't remembered anywhere), so
tsubst_expr tries to build a new decl.  The type of the proxy refers to the
closure parameter, and we also can't find the corresponding parameter in the
instantiation, so we try to build a new one and abort when we try to
instantiate a lambda type.

This is aggravated for an xobj lambda like this one because the dummy op() is
iobj, so the expected closure parameter doesn't match the actual one at all. 
And the dummy op() is gone by the time we are substituting into the requires,
all we have is the real op().

I think building the dummy op() is wrong; the standard says that within the
parameter-declaration-clause naming an init-capture does not refer to a member
of the closure parameter of the op(), but rather the variable described in
https://eel.is/c++draft/expr#prim.lambda.capture-6
(and naming a non-init capture just refers to the captured variable).

Once we're past the parameter-declaration-clause, we should be able to update
the capture proxies to refer to the real op().  That's awkward with a trailing
return type, but we should be able to build the op() with auto return and
splice the trailing return after we parse it.

Reply via email to