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.