Skip to content

Clang complains about concept depending on itself #62096

Closed
@craffael

Description

@craffael

Version of Clang

clang version 17.0.0 (https://github.com/llvm/llvm-project.git 5b461d5ec172d21029da492064704fe3da6f8bab)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /opt/compiler-explorer/clang-trunk/bin

Steps to reproduce the problem

Try to compile the following program with clang++ main.cpp -std=c++20 -ftemplate-backtrace-limit=0:

#include <type_traits>

template <class OPERATOR>
concept Operator = std::is_nothrow_copy_constructible_v<OPERATOR>;

struct AnyOperator {

  template <Operator OP>
  explicit AnyOperator(OP op) noexcept {}

  /// Copy constructor
  AnyOperator(const AnyOperator&) noexcept = default;
};


static_assert(Operator<AnyOperator>);

It produces the following output (see also Godbolt):

<source>:4:20: error: satisfaction of constraint 'std::is_nothrow_copy_constructible_v<OPERATOR>' depends on itself
concept Operator = std::is_nothrow_copy_constructible_v<OPERATOR>;
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:4:20: note: while substituting template arguments into constraint expression here
concept Operator = std::is_nothrow_copy_constructible_v<OPERATOR>;
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:8:13: note: while checking the satisfaction of concept 'Operator<AnyOperator>' requested here
  template <Operator OP>
            ^
<source>:8:13: note: while substituting template arguments into constraint expression here
  template <Operator OP>
            ^~~~~~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/13.0.1/../../../../include/c++/13.0.1/type_traits:3306:7: note: while checking constraint satisfaction for template 'AnyOperator<AnyOperator>' required here
    = __is_nothrow_constructible(_Tp, __add_lval_ref_t<const _Tp>);
      ^~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/13.0.1/../../../../include/c++/13.0.1/type_traits:3306:7: note: in instantiation of function template specialization 'AnyOperator::AnyOperator<AnyOperator>' requested here
<source>:4:25: note: in instantiation of variable template specialization 'std::is_nothrow_copy_constructible_v<AnyOperator>' requested here
concept Operator = std::is_nothrow_copy_constructible_v<OPERATOR>;
                        ^
<source>:4:20: note: while substituting template arguments into constraint expression here
concept Operator = std::is_nothrow_copy_constructible_v<OPERATOR>;
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:16:15: note: while checking the satisfaction of concept 'Operator<AnyOperator>' requested here
static_assert(Operator<AnyOperator>);
              ^~~~~~~~~~~~~~~~~~~~~
<source>:16:1: error: static assertion failed
static_assert(Operator<AnyOperator>);
^             ~~~~~~~~~~~~~~~~~~~~~
<source>:16:15: note: because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression
static_assert(Operator<AnyOperator>);
              ^
2 errors generated.

Correct behavior

Clang should accept the code. As far as I know the code is valid. It compiles fine with MSVC and GCC.

Metadata

Metadata

Assignees

No one assigned

    Labels

    c++20clang:frontendLanguage frontend issues, e.g. anything involving "Sema"conceptsC++20 concepts

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions