[libcxx-commits] [clang] [libcxx] [Clang] Normalize constraints before checking for satisfaction (PR #161671)
Lei Wang via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Oct 6 14:36:10 PDT 2025
wlei-llvm wrote:
> @wlei-llvm We would appreciate it if you can provide us with a self-contained reproducer, otherwise there's nothing we can do.
Hi @zyn0217 , here is a reproducer:
test.cpp:
```
#include <range/v3/view.hpp>
#include <range/v3/view/filter.hpp>
#include <range/v3/view/iota.hpp>
void foo() {
std::vector<int> a = ranges::views::iota(0, 1)
| ranges::to_vector;
std::vector<int> b = ranges::views::iota(0, 1)
| ranges::views::filter([&](const auto& col) { return true; })
| ranges::to_vector;
}
```
And it can be reproduced by the `range-v3` truck: https://github.com/ericniebler/range-v3
Cmd:
```
clang++ test.cpp -I range-v3/include/ -std=c++20 -c
```
Error:
```
In file included from test.cpp:3:
In file included from range-v3/include/range/v3/view.hpp:17:
In file included from range-v3/include/range/v3/view/adaptor.hpp:28:
In file included from range-v3/include/range/v3/view/all.hpp:26:
In file included from range-v3/include/range/v3/view/ref.hpp:25:
range-v3/include/range/v3/view/interface.hpp:233:59: error: invalid operands to binary expression ('detail::facade_sentinel_t<ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)>>>' (aka 'ranges::basic_iterator<ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)>>::adaptor>>') and 'detail::facade_iterator_t<ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)>>>' (aka 'basic_iterator<ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)>>::adaptor>>'))
233 | return static_cast<size_type>(derived().end() - derived().begin());
| ~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~
range-v3/include/range/v3/range/primitives.hpp:138:35: note: in instantiation of function template specialization 'ranges::view_interface<ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)>>>::size<true>' requested here
138 | return ((R &&) r).size();
| ^
range-v3/include/range/v3/range/conversion.hpp:325:39: note: in instantiation of function template specialization 'ranges::_size_::fn::operator()<ranges::filter_view<ranges::iota_view<int, int>, (lambda at test.cpp:14:34)> &>' requested here
325 | auto const rng_size = ranges::size(rng);
| ^
range-v3/include/range/v3/range/conversion.hpp:346:24: note: in instantiation of function template specialization 'ranges::detail::to_container::fn<ranges::detail::from_range<std::vector>>::impl<std::vector<int>, ranges::basic_iterator<ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)>>::adaptor>>, ranges::filter_view<ranges::iota_view<int, int>, (lambda at test.cpp:14:34)>>' requested here
346 | return impl<cont_t, iter_t>(static_cast<Rng &&>(rng), use_reserve_t{});
| ^
range-v3/include/range/v3/range/conversion.hpp:276:24: note: in instantiation of function template specialization 'ranges::detail::to_container::fn<ranges::detail::from_range<std::vector>>::operator()<ranges::filter_view<ranges::iota_view<int, int>, (lambda at test.cpp:14:34)>>' requested here
276 | return static_cast<Fn &&>(fn)(static_cast<Rng &&>(rng));
| ^
range-v3/include/range/v3/iterator/basic_iterator.hpp:803:5: note: candidate template ignored: constraints not satisfied [with Cur = ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)>>::adaptor>]
803 | operator-(basic_iterator<Cur> left, typename basic_iterator<Cur>::difference_type n)
| ^
range-v3/include/range/v3/iterator/basic_iterator.hpp:801:18: note: because 'ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)>>::adaptor>' does not satisfy 'random_access_cursor'
801 | requires detail::random_access_cursor<Cur>)
| ^
range-v3/include/range/v3/detail/prologue.hpp:35:26: note: expanded from macro 'template'
35 | template<__VA_ARGS__ CPP_TEMPLATE_AUX_ \
| ^
range-v3/include/range/v3/detail/range_access.hpp:378:13: note: because 'sized_sentinel_for_cursor<ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> >::adaptor>, ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> >::adaptor>>' evaluated to false
378 | sized_sentinel_for_cursor<T, T> && //
| ^
range-v3/include/range/v3/detail/range_access.hpp:329:30: note: because 'detail::sized_sentinel_for_cursor_requires_<ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> >::adaptor>, ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> >::adaptor>>' evaluated to false
329 | CPP_requires_ref(detail::sized_sentinel_for_cursor_, S, C);
| ^
range-v3/include/range/v3/detail/range_access.hpp:319:17: note: because 'range_access::distance_to(c, s) , concepts::requires_<signed_integer_like_<decltype(range_access::distance_to(c, s))>>' would be invalid: no matching function for call to 'distance_to'
319 | range_access::distance_to(c, s),
| ^
range-v3/include/range/v3/detail/range_access.hpp:319:17: note: and 'range_access::distance_to(c, s) , concepts::requires_<signed_integer_like_<decltype(range_access::distance_to(c, s))>>' would be invalid: no matching function for call to 'distance_to'
range-v3/include/range/v3/detail/range_access.hpp:329:30: note: and 'detail::sized_sentinel_for_cursor_requires_<ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> >::adaptor>, ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> >::adaptor>>' evaluated to false
329 | CPP_requires_ref(detail::sized_sentinel_for_cursor_, S, C);
| ^
range-v3/include/range/v3/detail/range_access.hpp:319:17: note: because 'range_access::distance_to(c, s) , concepts::requires_<signed_integer_like_<decltype(range_access::distance_to(c, s))>>' would be invalid: no matching function for call to 'distance_to'
319 | range_access::distance_to(c, s),
| ^
range-v3/include/range/v3/detail/range_access.hpp:319:17: note: and 'range_access::distance_to(c, s) , concepts::requires_<signed_integer_like_<decltype(range_access::distance_to(c, s))>>' would be invalid: no matching function for call to 'distance_to'
range-v3/include/range/v3/iterator/basic_iterator.hpp:811:5: note: candidate template ignored: constraints not satisfied [with Cur2 = ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)>>::adaptor>, Cur = ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)>>::adaptor>]
811 | operator-(basic_iterator<Cur2> const & left, basic_iterator<Cur> const & right)
| ^
range-v3/include/range/v3/iterator/basic_iterator.hpp:809:18: note: because 'detail::sized_sentinel_for_cursor<ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> >::adaptor>, ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> >::adaptor>>' evaluated to false
809 | requires detail::sized_sentinel_for_cursor<Cur2, Cur>)
| ^
range-v3/include/range/v3/detail/prologue.hpp:35:26: note: expanded from macro 'template'
35 | template<__VA_ARGS__ CPP_TEMPLATE_AUX_ \
| ^
range-v3/include/range/v3/detail/range_access.hpp:329:30: note: because 'detail::sized_sentinel_for_cursor_requires_<ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> >::adaptor>, ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> >::adaptor>>' evaluated to false
329 | CPP_requires_ref(detail::sized_sentinel_for_cursor_, S, C);
| ^
range-v3/include/range/v3/detail/range_access.hpp:319:17: note: because 'range_access::distance_to(c, s) , concepts::requires_<signed_integer_like_<decltype(range_access::distance_to(c, s))>>' would be invalid: no matching function for call to 'distance_to'
319 | range_access::distance_to(c, s),
| ^
range-v3/include/range/v3/iterator/basic_iterator.hpp:819:5: note: candidate template ignored: constraints not satisfied [with S = detail::facade_sentinel_t<ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)>>>, Cur = ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)>>::adaptor>]
819 | operator-(S const & left, basic_iterator<Cur> const & right)
| ^
range-v3/include/range/v3/iterator/basic_iterator.hpp:817:18: note: because 'detail::sized_sentinel_for_cursor<detail::facade_sentinel_t<ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> > >, ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> >::adaptor>>' evaluated to false
817 | requires detail::sized_sentinel_for_cursor<S, Cur>)
| ^
range-v3/include/range/v3/detail/prologue.hpp:35:26: note: expanded from macro 'template'
35 | template<__VA_ARGS__ CPP_TEMPLATE_AUX_ \
| ^
range-v3/include/range/v3/detail/range_access.hpp:328:13: note: because 'sentinel_for_cursor<ranges::basic_iterator<ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> >::adaptor> >, ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> >::adaptor>>' evaluated to false
328 | sentinel_for_cursor<S, C> &&
| ^
range-v3/include/range/v3/detail/range_access.hpp:271:30: note: because 'detail::sentinel_for_cursor_requires_<ranges::basic_iterator<ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> >::adaptor> >, ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> >::adaptor>>' evaluated to false
271 | CPP_requires_ref(detail::sentinel_for_cursor_, S, C);
| ^
range-v3/include/range/v3/detail/range_access.hpp:261:17: note: because 'range_access::equal(c, s) , concepts::requires_<convertible_to<decltype(range_access::equal(c, s)), bool>>' would be invalid: no matching function for call to 'equal'
261 | range_access::equal(c, s),
| ^
range-v3/include/range/v3/detail/range_access.hpp:261:17: note: and 'range_access::equal(c, s) , concepts::requires_<convertible_to<decltype(range_access::equal(c, s)), bool>>' would be invalid: no matching function for call to 'equal'
range-v3/include/range/v3/iterator/basic_iterator.hpp:826:5: note: candidate template ignored: constraints not satisfied [with Cur = ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)>>::adaptor>, S = detail::facade_iterator_t<ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)>>>]
826 | operator-(basic_iterator<Cur> const & left, S const & right)
| ^
range-v3/include/range/v3/iterator/basic_iterator.hpp:824:18: note: because 'detail::sized_sentinel_for_cursor<detail::facade_iterator_t<ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> > >, ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> >::adaptor>>' evaluated to false
824 | requires detail::sized_sentinel_for_cursor<S, Cur>)
| ^
range-v3/include/range/v3/detail/prologue.hpp:35:26: note: expanded from macro 'template'
35 | template<__VA_ARGS__ CPP_TEMPLATE_AUX_ \
| ^
range-v3/include/range/v3/detail/range_access.hpp:328:13: note: because 'sentinel_for_cursor<ranges::basic_iterator<ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> >::adaptor> >, ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> >::adaptor>>' evaluated to false
328 | sentinel_for_cursor<S, C> &&
| ^
range-v3/include/range/v3/detail/range_access.hpp:271:30: note: because 'detail::sentinel_for_cursor_requires_<ranges::basic_iterator<ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> >::adaptor> >, ranges::adaptor_cursor<ranges::basic_iterator<ranges::iota_view<int, int>::cursor>, ranges::remove_if_view<ranges::iota_view<int, int>, ranges::logical_negate<(lambda at test.cpp:14:34)> >::adaptor>>' evaluated to false
271 | CPP_requires_ref(detail::sentinel_for_cursor_, S, C);
| ^
range-v3/include/range/v3/detail/range_access.hpp:261:17: note: because 'range_access::equal(c, s) , concepts::requires_<convertible_to<decltype(range_access::equal(c, s)), bool>>' would be invalid: no matching function for call to 'equal'
261 | range_access::equal(c, s),
| ^
range-v3/include/range/v3/detail/range_access.hpp:261:17: note: and 'range_access::equal(c, s) , concepts::requires_<convertible_to<decltype(range_access::equal(c, s)), bool>>' would be invalid: no matching function for call to 'equal'
range-v3/include/range/v3/iterator/common_iterator.hpp:290:27: note: candidate template ignored: could not match 'common_iterator' against 'ranges::basic_iterator'
290 | iter_difference_t<I2> operator-(common_iterator<I1, S1> const & x,
| ^
range-v3/include/range/v3/iterator/counted_iterator.hpp:377:37: note: candidate template ignored: could not match 'counted_iterator' against 'ranges::basic_iterator'
377 | constexpr iter_difference_t<I2> operator-(counted_iterator<I1> const & x,
| ^
range-v3/include/range/v3/iterator/counted_iterator.hpp:384:36: note: candidate template ignored: could not match 'counted_iterator' against 'ranges::basic_iterator'
384 | constexpr iter_difference_t<I> operator-(counted_iterator<I> const & x,
| ^
range-v3/include/range/v3/iterator/counted_iterator.hpp:391:36: note: candidate template ignored: could not match 'counted_iterator' against 'basic_iterator'
391 | constexpr iter_difference_t<I> operator-(default_sentinel_t,
| ^
1 error generated.
```
Thanks!
https://github.com/llvm/llvm-project/pull/161671
More information about the libcxx-commits
mailing list