On Fri, 4 Apr 2025, Patrick Palka wrote:

> On Fri, 4 Apr 2025, Jason Merrill wrote:
> 
> > On 4/4/25 4:35 PM, Patrick Palka wrote:
> > > On Fri, 4 Apr 2025, Jason Merrill wrote:
> > > 
> > > > Tested x86_64-pc-linux-gnu, applying to trunk.
> > > > 
> > > > -- 8< --
> > > > 
> > > > Since r10-7441 we set processing_template_decl in a requires-expression 
> > > > so
> > > > that we can use tsubst_expr to evaluate the requirements, but that
> > > > confuses
> > > > lambdas terribly; begin_lambda_type silently returns error_mark_node and
> > > > we
> > > > continue into other failures.  This patch clears 
> > > > processing_template_decl
> > > > again while we're defining the closure and op() function, so it only
> > > > remains
> > > > set while parsing the introducer (i.e. any init-captures) and building 
> > > > the
> > > > resulting object.  This properly avoids trying to create another lambda 
> > > > in
> > > > tsubst_lambda_expr.
> > > 
> > > I wonder if we couldn't just set current_template_parms to a dummy
> > > template parameter list if it's empty when parsing a requires-expr?
> > 
> > I don't see the benefit of making a requires-expr even more template-like;
> > IIUC the change to set processing_template_decl was largely for convenience
> > because the implementation expects template trees, I don't think it
> > corresponds to anything in the language.
> > 
> > https://eel.is/c++draft/expr#prim.req.general-note-1
> 
> Personally, I wouldn't mind it making it more template-like, and IMHO
> their current specification kind of forces them to be template-like in
> our templated vs non-templated tree dichotomy.
> 
> That's because requires-exprs are special in that nested-requirements
> are always templated (since constraints are always templated, I think),

On second thought it's not clear that constraint-expressions are always
templated.  But I guess since satisfaction is specified in terms of
template argument substitution into atomic constraints, which can only
be done on templated trees, it's implied that atomic constraints are
always templated and hence constraint-expressions must be templated.

So nested-requirements seem to be the one exception to the rule that
templated trees can only occur inside a template context, which kind
of seems like a soundness/consistency issue in the language?  I guess
we can narrowly resolve this by pretending nested-requirements introduce
a dummy template context if there isn't one already, but it seems more
convenient to pretend requires-expressions as a whole do so.

> and nested-requirements can contain requires-exprs.  So either we need
> to distinguish between templated and non-templated requires-exprs
> outside a template context when evaluating them (i.e. the former still
> need to be tsubst'd, the latter only need other kinds of checks e.g.
> convert_to_void and return-type-requirement checks), or we assume
> requires-exprs are always templated; IMHO the latter fits better
> with our templated vs non-templated tree dichotomy.
> 
> Note even if cp_parser_requires_expression didn't set
> processing_template_decl, IIUC we would still mishandle e.g.
> 
>   requires { requires requires { []{}; } };
> 
> without your patch.
> 
> > 
> > Jason
> > 
> > 
> 

Reply via email to