https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97407

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Reduced:

template<typename T> T&& declval;

template<typename R> decltype(declval<R&>().begin()) begin_impl(R&);

template<typename R>
using iter_type_impl = decltype(begin_impl(declval<R&>()));

template<typename Wat>
struct unrelated
{
  using erm = iter_type_impl<Wat>;
};

template<typename R>
using iterator_t = iter_type_impl<R>;

template<typename T> concept False = false;

template<typename R>
requires False<iterator_t<R>>
void f(R&)
{ }

int main()
{
  int a[2];
  f(a);
}


alias.C: In function ‘int main()’:
alias.C:27:6: error: use of function ‘void f(R&) [with R = int [2]]’ with
unsatisfied constraints
   27 |   f(a);
      |      ^
alias.C:21:6: note: declared here
   21 | void f(R&)
      |      ^
alias.C:21:6: note: constraints not satisfied
alias.C: In instantiation of ‘void f(R&) [with R = int [2]]’:
alias.C:27:6:   required from here
alias.C:17:30:   required for the satisfaction of ‘False<decltype
(begin_impl(declval<Wat&>()))>’ [with Wat = int[2]]
alias.C:17:38: note: the expression ‘false’ evaluated to ‘false’
   17 | template<typename T> concept False = false;
      |                                      ^~~~~


Here we print decltype (begin_impl(declval<Wat&>())) which would be better left
as iterator_t<R>, especially because "Wat" comes from a completely unrelated
class template which isn't even instantiated, but happens to use the same alias
template as iterator_t uses.

Reply via email to