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

Patrick Palka <ppalka at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
      Known to fail|                            |10.2.0, 11.0

--- Comment #1 from Patrick Palka <ppalka at gcc dot gnu.org> ---
This happens because of the following chain of events:

1. Calling basic_istream_view::begin() entails instantiating its definition to
perform return type deduction.
2. We perform overload resolution of the direct-initialization _Iterator{*this}
inside its definition.
3. As part of overload resolution, we consider the copy ctor _Iterator(const
_Iterator&).
4. We try to find an implicit conversion sequence from basic_istream_view to
const _Iterator&.
5. We consider a conversion sequence that goes through the conversion function
view_interface::operator bool().
6. We check the conversion function's constraint 'requires {
ranges::empty(_M_derived()); }'.
7. ranges::empty() checks that view_interface::empty() is callable and
therefore has satisfied constraints
8. view_interface::empty() requires range<basic_istream_view>, which requires
that basic_istream_view::begin() is callable, which requires that we deduce its
return type.  But we're already in the the middle of deducing it, so we hit a
SFINAE error, which causes satisfaction of range<basic_istream_view> to fail.
9. We cache this negative satisfaction result for (the atomic constraint of)
range<basic_istream_view>.
10. We rule out the copy ctor during overload resolution and eventually resolve
the direct-initialization in the expected way.

When we later evaluate the static assert, we just return the cached
satisfaction result.

I have an experimental patch here
https://gcc.gnu.org/pipermail/gcc-patches/2020-October/557117.html that makes
us rule out the conversion function in step 5 sooner without first checking its
constraints, which would be one way to fix this.

Reply via email to