On Wed, Apr 16, 2025 at 1:32 PM Jonathan Wakely <jwak...@redhat.com> wrote:
> On Wed, 16 Apr 2025 at 12:18, Jonathan Wakely <jwak...@redhat.com> wrote: > > > > This fixes: > > FAIL: 17_intro/headers/c++1998/operator_names.cc -std=gnu++23 (test for > excess errors) > > FAIL: 17_intro/headers/c++1998/operator_names.cc -std=gnu++26 (test for > excess errors) > > > > The purpose of 'not defined<format_kind<R>>' is to be ill-formed (as > > required by [format.range.fmtkind]) and to give an error that includes > > the string "not defined<format_kind<R>>". That was intended to tell you > > that format_kind<R> is not defined, just like it says! > > > > But user code can use -fno-operator-names so we can't use 'not' here, > > and "! defined" in the diagnostic doesn't seem as user-friendly. It also > > raises questions about whether it was intended to be the preprocessor > > token 'defined' (it's not) or where 'defined' is defined (it's not). > > > > Replace it with __no_primary_template<format_kind<R>> and a comment, > > which seems almost as good. The diagnostic now looks like: > > > > In file included from fmt.cc:1: > > .../include/c++/15.0.1/format: In instantiation of 'constexpr const auto > std::format_kind<int>': > > fmt.cc:3:15: required from here > > 3 | auto i = std::format_kind<int>; > > | ^~~~~~~~~~~~~~~~ > > .../include/c++/15.0.1/format:5164:31: error: use of > 'std::format_kind<int>' before deduction of 'auto' > > 5164 | = __no_primary_template(format_kind<_Rg>); // must define > specialization > > | ^~~~~~~~~~~~~~~~ > > .../include/c++/15.0.1/format:5164:30: error: '__no_primary_template' > was not declared in this scope > > 5164 | = __no_primary_template(format_kind<_Rg>); // must define > specialization > > | ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~ > > Maybe "must define specialization" isn't really ideal, because the > problem might be that users are trying to use format_kind<const R> > when they should use format_kind<R>, and telling them to define a > specialization for const R is wrong. I do not think that user's are expected to use format_kind directly will be confused by current specialization. I think you could adjust the comment: // must define specialization or _Rg is reference or cv-qualified type > They should just stop using const > R there. Similarly, if they try to use it for a type which is not an > input_range (like int in the error above) then we don't want to > encourage them to specialize the template for int, they should stop > their nonsense instead. > > So maybe this instead? > > .../include/c++/15.0.1/format:5164:50: error: > '__only_defined_for_non_const_input_ranges' was not declared > in this scope > 5164 | = __only_defined_for_non_const_input_ranges(format_kind<_Rg>); > | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~ > > > > > > > > > > libstdc++-v3/ChangeLog: > > > > * include/std/format (format_kind): Do not use 'not' > > alternative token to make the primary template ill-formed. > > Use __no_primary_template as the undefined identifier that will > > appear in diagnostics. > > --- > > > > Testing now on x86_64-linux. > > > > libstdc++-v3/include/std/format | 3 ++- > > 1 file changed, 2 insertions(+), 1 deletion(-) > > > > diff --git a/libstdc++-v3/include/std/format > b/libstdc++-v3/include/std/format > > index b1455977c65..9ce9b3cfed1 100644 > > --- a/libstdc++-v3/include/std/format > > +++ b/libstdc++-v3/include/std/format > > @@ -5160,7 +5160,8 @@ namespace __format > > > > /// @cond undocumented > > template<typename _Rg> > > - constexpr auto format_kind = not defined(format_kind<_Rg>); > > + constexpr auto format_kind > > + = __no_primary_template(format_kind<_Rg>); // must define > specialization > > > > template<typename _Tp> > > consteval range_format > > -- > > 2.49.0 > > > >