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

--- Comment #5 from Patrick Palka <ppalka at gcc dot gnu.org> ---
(In reply to Frank B. Brokken from comment #4)
> Dear ppalka at gcc dot gnu.org, you wrote:
> > 
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100288
> > 
> > Patrick Palka <ppalka at gcc dot gnu.org> changed:
> > 
> >            What    |Removed                     |Added
> > ----------------------------------------------------------------------------
> >            Keywords|                            |ice-on-invalid-code
> >            See Also|                            |https://gcc.gnu.org/bugzill
> >                    |                            |a/show_bug.cgi?id=99599
> > 
> > --- Comment #3 from Patrick Palka <ppalka at gcc dot gnu.org> ---
> > Agreed, the testcase looks invalid much like PR99599.  One workaround for
> > avoiding the constraint recursion here would be to change the signature of
> > 
> >   template <OstreamInsertable Type>
> >   inline void operator<<(CSVTabIns &&tab, Type const &value)
> > 
> > to something like
> > 
> >   template <std::same_as<std::remove_cvref_t<CSVTabIns>> U, 
> > OstreamInsertable
> > Type>
> >   inline void operator<<(U &&tab, Type const &value)
> > 
> > so that the constraint OstreamInsertable<Type> is checked on this overload 
> > only
> > if the first argument to << has the expected type.
> > 
> > -- 
> > You are receiving this mail because:
> > You reported the bug.
> 
> Hi Patrick,
> 
> Thanks for your e-mail.
> 
> Since (AFAICS) you directly and only sent your e-mail to me I'm wondering
> whether you want me to comment on your e-mail. It's getting kind of late
> here,
> but I could send a more extensive reply tomorrow. Let me know if that's what
> you want.

Oh sorry, that was just an automated email for the comment I posted to the
bugzilla PR, which gets sent to everyone on the CC list of the PR.  I wasn't
expecting any sort of reply :)

> 
> I tried your suggestion, and it seems to solve the issue. But at the same
> time
> it puzzles me why 
> 
>     template <OstreamInsertable Type>
>     inline void operator<<(CSVTabIns &&tab, Type const &value)
>     {}
> 
> won't be instantiated for FMT in
> 
>     inline void operator<<(CSVTabIns &tab, FMT::FMTHline hline)
>     {
>         tab << (*hline)(1);      // insert hline in the next column
>     }
> 
> when FMT defines FMTHline as  'typedef FMT (*FMTHline)(unsigned)' and 
> 
>     std::ostream &operator<<(std::ostream &out, FMT const &fmt)
> 
> is declared. I would have expected that 
> 
>         tab << (*hline)(1);      // insert hline in the next column
> 
> would cause the compiler to instantiate 
> 
>     template <OstreamInsertable Type>
>     inline void operator<<(CSVTabIns &&tab, Type const &value)
>     {}
> 
> for Type = FMT.
> 


The compiler does try to instantiate that overload for Type = FMT there, but
when checking the constraint OstreamInsertable<FMT> on this overload it needs
to resolve the << in

    requires(std::ostream &out, Type value)
    {
        out << value;
    };

for Type = FMT, during which it considers that same operator<< overload.  And
CWG2369 says we now first check constraints before non-dependent conversions,
but we're in the middle of checking the constraints on this overload, so we
enter a constraint loop.

> Maybe I'm missing something here? And it's also not something that caused the
> compiler's internal error.

Yeah, we shouldn't be seeing an internal error even on an invalid testcase. 
This needs to be fixed.

Reply via email to