Issue 75893
Summary Clang gives incorrect error about constraint depending upon itself
Labels clang
Assignees
Reporter jacobsa
    Here is a simple program where we construct a `std::function` from a callable type with a templated constructor. The constructor is compatible with any input where it can create its own copy from the input forwarding reference.

```c++
#include <functional>
#include <type_traits>

struct Callable {
    Callable() = default;
 Callable(const Callable&) = default;
    Callable& operator=(const Callable&) = default;

    template <typename F>
    requires requires {
      // We don't want this constructor to interfere with the copy
      // constructor.
      requires(!std::is_same_v<Callable, std::decay_t<F>>);

      // It must be possible to make our own copy of the input from
      // the input reference.
      requires std::is_constructible_v<std::decay_t<F>, F>;
    }
    Callable(F&& f);

    int operator()();
};

void foo() { std::function<int()> f = Callable{}; }
```

GCC [accepts](https://godbolt.org/z/PchvYqG68) this program as valid with `-std=c++20`, but clang [rejects it](https://godbolt.org/z/YzxE68Pfn) at trunk using `-std=c++20 -stdlib=libc++`, with the following error:

```
<source>:10:14: error: satisfaction of constraint 'requires { requires (!std::is_same_v<Callable, std::decay_t<F> >); requires std::is_constructible_v<std::decay_t<F>, F>; }' depends on itself
   10 | requires requires {
      | ^~~~~~~~~~
[...]
<snip>compressed_pair.h:129:22: note: while checking constraint satisfaction for template 'Callable<std::tuple<const Callable &>>' required here
```

But it's not true that this constraint depends upon itself. If you substitute in `std::tuple<const Callable &>` for `F`, you get:
  
```c++
requires(!std::is_same_v<Callable, std::decay_t<std::tuple<const Callable &>>>);
  
requires std::is_constructible_v<
    std::decay_t<std::tuple<const Callable &>>,
    std::tuple<const Callable &>>;
```

Neither of these should depend on anything to do with that constructor, as far as I can tell.

Note that clang [_does_ accept](https://godbolt.org/z/hs7s17zPs) this program if we don't use `-stdlib=libc++`. It's possible this is a bug in libc++, or it's just an accident of how the type traits are implemented in libc++, triggering a compiler bug that we don't see otherwise.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to