Hello,

I'm seeking feedback on how best to handle deep or infinite recursion in
concept satisfaction. Please let me know if there's a better place to ask.

Recursion in satisfaction can occur a few ways, some of which has been fixed by
moving the point of declaration of a concept to prevent directly referencing
itself. However, there's still an issue where overload resolution requires a
concept satisfaction check which depends on the initial overload, etc:

template<typename T>
concept Fooable = requires(T t) { foo(t); };

template<Fooable T>
void foo(T t) { }

Here foo is enabled if it's enabled. PR c++/67934 is an example of this in the
wild, where a default impl of op== depends on op!= and a vice-versa.

I have a patch that addresses this form of recursion -- where the same
requirements are being satisfied with the same arguments -- with an explicit
error message, but it's also possible to get into deep recursion with unique
arguments:

template<int N, typename T>
concept Foo = requires(T t) { foo<N - 1>(t); };

template<int N = 1024 * 1024, typename T = int>
  requires Foo<N, T>
int foo(T t) { return foo<N - 1>(t); }

Similar cases without concepts are handled with
-ftemplate-depth/max_tinst_depth but satisfaction on trunk does not currently
pass through anything that increments tinst_depth.


Is a patch that errors on direct recursion wanted, should it be handled by some
generic depth marker, or is there a better fix?

If a depth marker should be used, should max_tinst_depth be reused, or should a
separate (configurable?) value be used?

Related to the above, should pt.c be reworked or does this seem like something
that should be handled directly in constraint.cc?


Any feedback would be appreciated.

Thank you,
Jeff Chapman II

Reply via email to