Hi.

While investigating a fix for C++/PR115030 (a bug in constrained auto
deduction), I was wondering why we are not substituting constraint args of an
auto node in tsubst (pt.cc:16533). Instead, this substitution is delayed until
do_auto_deduction (pt.cc), where we attempt to find the substituted args of the
enclosing scope. At that point, it becomes difficult to find partially
specialised args, as they are erased in the process. I propose modifying tsubst
to eagerly substitute the constraint args of an auto node.

By making this change, we would not need to provide outer_targs for
do_auto_deduction in cases where tsubst has been called for the type, which
covers most scenarios. However, we still need outer_targs for cases like:

template <typename T, C<T> auto V>
struct S { };

Hence, outer_targs cannot be completely removed but will be set to TREE_NULL in
all calls except the one in convert_template_argument (pt.cc:8788).
Additionally, the tmpl argument of do_auto_deduction, which helps to provide
outer args in the scope, will no longer be necessary and can be safely
removed.

Also, the trimming hack proposed in
https://gcc.gnu.org/pipermail/gcc-patches/2024-June/654724.html to address
C++/PR114915 is no longer needed. We will add an assertion to ensure that the
missing levels do not become negative.

Substituting constraint arguments earlier will slightly alter error messages
(see testsuite/g++.dg/cpp2a/concepts-placeholder3.C as an example).

To summarise, I have made the following changes:
- Modified tsubst to substitute the constraint args.
- Fixed shallow checks for using the cache from TEMPLATE_TYPE_DESCENDANTS
(pt.cc:16513).
- Substituted the constraint args and the auto node itself, while retaining all
other parameters as is (pt.cc:16533).
- Removed now unnecessary code that attempted to find outer scope template info
and args in various locations.
- Updated the missing levels hack (pt.cc:31320) to work with the substituted
constraints.
- Used level instead of orig_level to find the missing levels.
- Added an assertion for future safety.

Details of these changes can be found in the patch "[PATCH v1] c++: Eagerly
substitute auto constraint args in tsubst [PR115030]" that will be replied to
this thread.

This patch, in my opinion, improves code quality by removing an argument from
do_auto_deduction and eliminating the out-of-scope task of finding outer_targs
within do_auto_deduction. It simplifies the usage of do_auto_deduction and
resolves C++/PR115030 without complex calculations for specialised args. It
also enhances the consistency of tsubst behaviour by not leaving constraints
un-substituted. However, these changes make args in constraints_satisfied_p
(being called from do_auto_deduction) a bit misleading, as it will not carry
the actual args of the constraint and can even be an empty vec.

I have added a testsuite for C++/PR115030, and as far as I have tested (only
c++ dg.exp on x86_64-linux), there are no regressions.

Extra:
While doing this, I also realised that the hash function in ctp_hasher (for
canonical type of template parameters) slightly differs from its equality
function. Specifically, the equality function uses comptypes (typeck.cc) (with
COMPARE_STRUCTURAL) and compares placeholder constraints (typeck.cc:1586),
while the hash function ignores them (pt.cc:4528). As a result, we can have two
types with equal hashes that are unequal. For example, assuming:

template <typename T, typename U>
concept C1 = ...

template <typename T, typename U>
concept C2 = ...


"C1<U> auto" and "C2<V> auto" have the same hash value but are unequal. This
issue does not cause any error (it is a hash collision and it is handled), but
it can be avoided by using hash_placeholder_constraint (constraint.cc:1150).

Therefore, I have made the following changes:
- Fixed the hash function to calculate the hash of the constraint (pt.cc:4528).
- Slightly modified the existing hash_placeholder_constraint
(constraint.cc:1150) to accept the initial hash value as an argument.

Details of these changes can be found in the patch "[PATCH v1] c++: Hash
placeholder constraint in ctp_hasher" that will be replied to this email.

Thanks. I really appreciate your comments and feedback on these proposed
changes.

Reply via email to