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

--- Comment #8 from Patrick Palka <ppalka at gcc dot gnu.org> ---
(In reply to Tomasz KamiƄski from comment #7)
> >> I also added a 'size(t) > 0' check and a check for a type that is not >> 
> >> statically sized, where the concept shouldn't become ill-formed either.
> >
> > FWIW I think GCC is correct to diagnose this due to 
> > https://eel.is/c++draft/temp.constr#atomic-3, which mandates that an atomic 
> > constraint after substitution yields a constant expression of type bool, 
> > but here it's non-constant.
> 
> Isn't check `typename i<size(t)>;` (that is placed before) guarding the
> later requires? It can only pass if size(t) is constant. Or requirements
> inside require expr do not short-circuit?
Good point, requirements should indeed short-circuit and so the testcase as
written is well-formed.  I had the first requirement commented out, which I
forgot to mention :)

So for sake of completeness,

  template <typename T>
  concept StaticSizedRange = requires (T &&t) { requires (size (t) > 0); };

  static_assert(!StaticSizedRange<v>);

is correctly diagnosed as ill-formed due to the satisfaction value being
well-formed but non-constant.  In order to treat non-constantness as false
instead of ill-formed, we need to encode the requirement as a template
argument, e.g.

  template <typename T>
  concept StaticSizedRange = requires (T &&t) { typename bool_constant<(size(t)
> 0)>; };

  static_assert(!StaticSizedRange<v>);

which GCC incorrectly rejects.  I submitted a tiny patch to fix this:
https://gcc.gnu.org/pipermail/gcc-patches/2025-April/679996.html

Reply via email to