[libcxx-commits] [clang] [libcxx] [Clang] Normalize constraints before checking for satisfaction (PR #141776)
Younan Zhang via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Sep 19 02:28:14 PDT 2025
================
@@ -2859,6 +2859,65 @@ This library is called by the :ref:`Parser library <Parser>` during parsing to
do semantic analysis of the input. For valid programs, Sema builds an AST for
parsed constructs.
+
+Concept Satisfaction Checking and Subsumption
+---------------------------------------------
+
+As per the C++ standard, constraints are
+ `normalized <https://eel.is/c++draft/temp.constr.normal>`_
+and the normal form is used both for subsumption, and constraint checking.
+Both depend on a parameter mapping that substitutes lazily. In particular,
+we should not substitute in unused arguments.
+
+Clang follows the order of operations prescribed by the standard.
+
+Normalization happens prior to satisfaction and subsumption
+and is handled by ``NormalizedConstraint``.
+
+Clang preserves in the normalized form intermediate concept-ids
+(``ConceptIdConstraint``) This is used for diagnostics only and no substitution
+happens in a ConceptIdConstraint if its expression is satisfied.
+
+The normal form of the associated constraints of a declaration is cached in
+Sema::NormalizationCache such that it is only computed once.
+
+a ``NormalizedConstraint`` is a recursive data structure, where each node
+contains a parameter mapping, represented by the indexes of all parameter
+being used.
+
+Checking satisfaction is done by ConstraintSatisfactionChecker, recursively
+walking NormalizedConstraint. At each level, we substitute the outermost
+level of the template arguments referenced in the parameter mapping of a
+normalized expression (``MultiLevelTemplateArgumentList``).
+
+.. code-block:: c++
+
+ template <typename T>
+ concept A = __is_same(T, int);
+
+ template <typename U>
+ concept B = A<U> && __is_same(U, int);
+
+The normal form of B is
+
+.. code-block:: c++
+ __is_same(T, int) /*T->U, innermost level*/
+ && __is_same(U, int) {U->U} /*T->U, outermost most level*/
+
+After substitution in the mapping, we substitute in the constraint expression
+using that copy of the MultiLevelTemplateArgumentList, and then evaluate it.
----------------
zyn0217 wrote:
```suggestion
using that copy of the ``MultiLevelTemplateArgumentList``, and then evaluate it.
```
https://github.com/llvm/llvm-project/pull/141776
More information about the libcxx-commits
mailing list