[libcxx-commits] [clang] [libcxx] [Clang] Normalize constraints before checking for satisfaction (PR #161671)
Devon Loehr via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Oct 3 14:11:16 PDT 2025
DKLoehr wrote:
After this PR we've started to see static-assert failures when building chromium. I've attached a minimized reproducer (from cvise, then manually cut down as much as I could).
The below code will fail after this PR, and succeed before it, when `clang++` is run with `-std=c++20`. The failure is
```
preprocessed.cc:38:15: error: static assertion failed due to requirement '!std::is_constructible_v<span<4>, array<int, 3>>'
38 | static_assert(!std::is_constructible_v<span<4>, array<int, 3>>);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
```
Unfortunately I don't totally understand the code myself, but this seems wrong: we certainly don't want to be able to initialize a 4-element thing from a 3-element thing, and the `FixedExtentConstructibleFromExtent` seems like it should be checking that the two numbers are equal.
Furthermore, we need _both_ static_asserts at the end of the file. Whichever happens second will fail, and if only one exists it will pass.
```
namespace std {
template <int __v>
struct integral_constant {
static const int value = __v;
};
template <class _Tp, class... _Args>
constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...);
template <class _From, class _To>
constexpr bool is_convertible_v = __is_convertible(_From, _To);
template <class>
struct tuple_size;
template <class _Tp>
constexpr decltype(sizeof(int)) tuple_size_v = tuple_size<_Tp>::value;
} // namespace std
template <int N, int X>
concept FixedExtentConstructibleFromExtent = X == N;
template <int Extent>
struct span {
int static constexpr extent = Extent;
template <typename R, int N = std::tuple_size_v<R>>
requires(FixedExtentConstructibleFromExtent<extent, N>)
span(R);
};
template <class, int>
struct array {};
template <class _Tp, decltype(sizeof(int)) _Size>
struct std::tuple_size<array<_Tp, _Size>> : integral_constant<_Size> {};
static_assert(std::is_convertible_v<array<int, 3>, span<3>>);
static_assert(!std::is_constructible_v<span<4>, array<int, 3>>);
```
https://github.com/llvm/llvm-project/pull/161671
More information about the libcxx-commits
mailing list