https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119203
Bug ID: 119203 Summary: A type with a constrained operator-> gives error: base operand of '->' has non-pointer type Product: gcc Version: 15.0 Status: UNCONFIRMED Keywords: diagnostic Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- template<typename T> struct Iter { T t; auto operator->() const requires(t.operator->()) { return t.operator->(); } }; struct S { int i; }; int main() { Iter<S> iter; iter->i; } When compiled with -std=c++20 this invalid code gives: arrow.cc: In function 'int main()': arrow.cc:14:7: error: base operand of '->' has non-pointer type 'Iter<S>' 14 | iter->i; | ^~ The code is invalid, but it would be better if the error said that the operator->() could not be used because its constraints were not satisfied, as any other member function would do. For example, a constrained operator* gives a good error: template<typename T> struct Iter { T t; int operator*() requires(*t) { return 1; } }; struct S { int i; }; int main() { Iter<S> iter; *iter; } arrow.cc: In function 'int main()': arrow.cc:14:3: error: no match for 'operator*' (operand type is 'Iter<S>') 14 | *iter; | ^~~~~ arrow.cc:14:3: note: there is 1 candidate arrow.cc:6:7: note: candidate 1: 'int Iter<T>::operator*() requires *((Iter<T>*)this)->Iter<T>::t [with T = S]' 6 | int operator*() requires(*t) { return 1; } | ^~~~~~~~ arrow.cc:6:7: note: constraints not satisfied arrow.cc: In instantiation of 'int Iter<T>::operator*() requires *((Iter<T>*)this)->Iter<T>::t [with T = S]': arrow.cc:14:4: required from here 14 | *iter; | ^~~~ arrow.cc:6:7: required by the constraints of 'template<class T> int Iter<T>::operator*() requires *((Iter<T>*)this)->Iter<T>::t' arrow.cc:6:28: error: no match for 'operator*' (operand type is 'S') 6 | int operator*() requires(*t) { return 1; } | ~^~~ This says there is no operator* for Iter<S> because its constraints were not satisfied, and tells us that's because *t isn't valid.