https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102975
--- Comment #3 from Patrick Palka <ppalka at gcc dot gnu.org> --- (In reply to Patrick Palka from comment #2) > (In reply to Andrew Pinski from comment #1) > > Hmm, this is interesting: > > template<class> concept Never = false; > > template<class T> concept C = Never<typename T::type>; > > void f() { > > struct X { > > // using type = int; > > }; > > static_assert(not C<X>); > > } > > > > is able to compile. I don't know enough about C++ concepts to say if this is > > valid or not but it looks like the type is really unused in the above case > > ... > > This is different from "constexpr bool" which requires the type to be > > defined ... > > Yeah, when evaluating a concept-id such as C<X> (which is done by > substituting {X} into the normal form of C), the normalization process > (https://eel.is/c++draft/temp.constr.normal) ignores arguments to unused > template parameters. > > So since 'Never' doesn't use its template parameter, during normalization of > C we discard the template argument 'typename T::type' passed to Never. The > normal form of C ends up being 'false (with empty parameter mapping)' which > is trivially satisfied for all T. ... trivially _unsatisfied_ rather