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.

Reply via email to