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. 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
>

Reply via email to