I will try again to recap the 3 questions. related to the constraints.
As general idea, I have got that an invalid type/expression leads the constraint just to fail if it is in immediate-context, otherwise to an ill-formed program if in non-immediate-context (e.g., in the body of a lambda expression),
provided that the verification of that type/expression is triggered by the fact that previous parts of the constraint (in the lexical order, e.g., in the pieces of a requires expression, or in the combined list of atomic constraints for a normal form) weren't able to determine already an overall result for the constraint (e.g., false for an AND combination, or true for an OR combination),
but also that an invalid type/expression always in place for a templated entity (i.e., regardless of the instantiation) represents an IFNDR case.
That said, I have reported in
https://lists.isocpp.org/std-discussion/2025/01/2783.php the text associated to both requires expression (
[expr.prim.req.general]-p5) and atomic constraint (
[temp.constr.atomic]-p3 and [temp.res.general]-p(6.4)),
and I have noticed two potential problematic topics when an atomic constraint is made by a requires expression.
I recall them in the following, and refine/fix details of the discussion.
Before discussing the detail of the first 2 questions, it is important to highlight that the normal form of the constraints associated to a function, is built according to rules from [temp.constr.normal], where no 'explosion' is indicated in case of requires expression, which means that a requires expression boils down to be an atomic constraint even when it contains multiple requirements (simple, type, compound, nested: [expr.prim.req.general]-p1).
A) the first topic is for the case when that requires expression contains a nested requirement, which therefore contains a constraint-expression, in turn supposed to contain AND / OR operators, combining further nested constraints/requirements; let's now suppose that one of these nested ones contains an invalid type/expression, but also that another constraint/requirement preceding in the lexical order, allows to provide a true value for the original requires expression.
If I would exactly apply the text of [temp.constr.atomic]-p3, then it reads that an invalid type/expression (in immediate context) leads soon the constraint to be not satisfied, whereas the rules from [expr.prim.req.general]-p5 postpone the check of invalid type/expression for each contained requirement only after that previous requirements have already been checked and successfully verified (true result), and similarly the rules from [temp.constr.op]-p2/p3 state that the constraints conjunctions and disjunctions are checked one by one, ignoring the residual ones as soon as a constraint allows to get a logical overall result.
Please, note that in my original post (2783), I erroneuosly considered a case with false overall logical result for the requires expression, and invoked only the rules from [expr.prim.req.general]-p5, but this is not a conflict because the final result as false is provided by both [temp.constr.atomic]-p3 and [expr.prim.req.general]-p5.
As highlighted in the second post (2787), I really believe that everything becomes clear and well consistent if the presence of an invaild type/expression within a requires expression does not mean that the requires expression is itself an invalid expression. Indeed, this would represent a hierarchical separation between the atomic constraint and what is inside the requires expression.
Please, let me know if this is true, and if in your opinion this is in some way already clear in the standard for any motivation (e.g., concept of 'immediate context', or anything else).
If the solution is in the definition of 'immediate context', don't you believe that the standard might state clearly something (similar to [temp.deduct.general]-p9) about the requirement-body not being part of the immediate context of an atomic constraint corresponding to the requires expression ? However, in such case, I would be also afraid of formally incorrectness about the effect of invalid within the requirements of the requires-expression (i.e., invalid in a non-immediate context for the original atomic constraint), and therefore some more note should be added to clarify that any decision is based on the rules for those requirements.
Otherwise (if none of the previous ones apply), do you believe (as I do) that the standard may be clarified in [temp.constr.atomic]-p3 when an atomic constraint is made by a requires expression, and eventually even in [expr.prim.req.general]-p5 in order to introduce a similar 'hierarchical separation' when one of the requirements is a nested requirement ? (but I don't know if it was really intended to have also the second mentioned kind of hierarchy... likely not).
B) the second topic is related to the cases of IFNDR when the invalid type/expression is always in place; indeed, [expr.prim.req.general]-p5 reads that the IFNDR is there anyway, which means regardless of any satisfation check is performed or not involving the part containing the invalid type/expression; on the contrary, [temp.res.general]-p(6.4) reads that the IFNDR is only effective with the additional condition that no satisfaction check is performed on the constraint-expression containing the always-invalid type/expression.
But, what happens if the invalid is in an immediate context, a check is performed, therefore (based on [temp.constr.atomic]-p3) the constraint is just not satisfied but no ill-forming is notified by the compiler ?
Is it really wanted to drop the IFNDR just because a check was performed ?
Can I state that if the invalid is inside a requires expression, the IFNDR remains anyway in place based on [expr.prim.req.general]-p5 ?
Was also here any hierarchical separation intended as discussed for previous topic ?
Note also that [temp.res.general]-p(6.4) makes no distinction between immediate and non-immediate contexts, nor between templated and non-templated entities -> is it really wanted not to have IF for non-immediate contexts ? Not even for non-templated entities (for them, Note 1 in [expr.prim.req.general]-p5 for requires expressions states IF instead of IFNDR) ?
Note finally that last part of [expr.prim.req.general]-p5 (after Note 1) seems not to be specific for immediate or non-immediate contexts, but I do believe that for non-immediate ones the intended behaviour is IF instead of IFNDR, isn't it ?
Last topic, with a short question:
C) (which was presented since the post 2783):
In [temp.constr.normal], the example in p1.4) reads that the atomic constraint-expression 'true' has empty mapping.
The point is that no rule from [temp.constr.normal] exactly states the possibility to get an empty mapping.
We have part p(1.9) as default case always indicating an identity mapping. I guess it should be extended to indicate empty mapping when the expression is constant, that is, not involving any template parameter (you know
for sure the best formal words to say it there).
I don't believe it's fair to consider the definition of this special case just through the example in p(1.4).
Thank you.