On Wed, 16 Apr 2025 at 15:22, Jonathan Wakely <jwak...@redhat.com> wrote: > > On Wed, 16 Apr 2025 at 12:59, Tomasz Kaminski <tkami...@redhat.com> wrote: > > > > > > > > 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 > > In general what appears in the diagnostic will only be one line, so if > we're adding a comment that we expect users to see, it needs to be > quite short. > > Although we could force it to span multiple lines like this: > > 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:5165:11: error: use of > 'std::format_kind<int>' before deduction of 'auto' > 5165 | format_kind<_Rg> // can specialize this for non-const > input ranges > | ^~~~~~~~~~~~~~~~ > .../include/c++/15.0.1/format:5164:16: error: > '__primary_template_not_defined' was not declared in this scope > 5164 | = __primary_template_not_defined( > | ~~~~~~~^ > 5165 | format_kind<_Rg> // can specialize this for non-const > input ranges > | > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 5166 | ); > | ~
This looks reasonable with Clang too: In file included from fmt.cc:1: .../include/c++/15.0.1/format:5164:9: error: use of undeclared identifier '__primary_template_not_defined' 5164 | = __primary_template_not_defined( | ^ .../include/c++/15.0.1/format:5165:11: note: in instantiation of variable template specialization 'std::format_kind<int>' requested here 5165 | format_kind<_Rg> // can specialize this for non-const input ranges | ^ fmt.cc:3:15: note: in instantiation of variable template specialization 'std::format_kind' requested here 3 | auto i = std::format_kind<int>; | ^ 1 error generated.