Skip to content

Conversation

cor3ntin
Copy link
Contributor

@cor3ntin cor3ntin commented Oct 2, 2025

In the standard, constraint satisfaction checking is done on the normalized form of a constraint.

Clang instead substitutes on the non-normalized form, which causes us to report substitution failures in template arguments or concept ids, which is non-conforming but unavoidable without a parameter mapping

This patch normalizes before satisfaction checking. However, we preserve concept-id nodes in the normalized form, solely for diagnostics purposes.

This addresses #61811 and related concepts conformance bugs, ideally to make the remaining implementation of concept template parameters easier

Fixes #135190
Fixes #61811

Co-authored-by: Younan Zhang [email protected]

@cor3ntin cor3ntin requested review from Endilll and a team as code owners October 2, 2025 14:00
@cor3ntin
Copy link
Contributor Author

cor3ntin commented Oct 2, 2025

Re-pushing #141776 while i investigate CI failures

Copy link

github-actions bot commented Oct 2, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@cor3ntin
Copy link
Contributor Author

cor3ntin commented Oct 2, 2025

@cor3ntin cor3ntin merged commit e9972de into llvm:main Oct 3, 2025
66 of 76 checks passed
MixedMatched pushed a commit to MixedMatched/llvm-project that referenced this pull request Oct 3, 2025
…161671)

In the standard, constraint satisfaction checking is done on the
normalized form of a constraint.

Clang instead substitutes on the non-normalized form, which causes us to
report substitution failures in template arguments or concept ids, which
is non-conforming but unavoidable without a parameter mapping

This patch normalizes before satisfaction checking. However, we preserve
concept-id nodes in the normalized form, solely for diagnostics
purposes.

This addresses llvm#61811 and
related concepts conformance bugs, ideally to make the remaining
implementation of concept template parameters easier

Fixes llvm#135190
Fixes llvm#61811

Co-authored-by: Younan Zhang
[[email protected]](mailto:[email protected])

---------

Co-authored-by: Younan Zhang <[email protected]>
@DKLoehr
Copy link
Contributor

DKLoehr commented Oct 3, 2025

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>>);

@ronlieb
Copy link
Contributor

ronlieb commented Oct 4, 2025

we are also seeing downstream failures related to this PR, seems to be with older GCC toolchains such as found on SLES 15 sp6. maybe revert and fix ?

/longer_pathname_so_that_rpms_can_support_packaging_the_debug_info_for_all_os_profiles/src/rocm_bandwidth_test/deps/work_bench/src/task_mgmt.cpp:435:5: error: no matching function for call to object of type 'const __copy_fn'
435 | std::ranges::copy(task_name | std::views::take(kMAX_THREAD_NAME_SIZE - 1), current_thread_name.begin());
| ^~~~~~~~~~~~~~~~~
/usr/lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13/bits/ranges_algobase.h:311:7: note: candidate template ignored: constraints not satisfied [with _Range = _Partial<std::ranges::views::_Take, decay_t<const std::basic_string<char, std::char_traits, std::allocator> &>, decay_t<const int &>>, _Out = iterator]
311 | operator()(_Range&& __r, _Out __result) const
| ^
/usr/lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13/bits/ranges_algobase.h:308:14: note: because '_Partial<std::ranges::views::_Take, decay_t<const std::basic_string<char, std::char_traits, std::allocator> &>, decay_t<const int &>>' (aka '_Partial<std::ranges::views::_Take, std::basic_string<char, std::char_traits, std::allocator>, int>') does not satisfy 'input_range'
308 | template<input_range _Range, weakly_incrementable _Out>
| ^
/usr/lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13/bits/ranges_base.h:590:27: note: because 'std::ranges::views::__adaptor::_Partial<std::ranges::views::_Take, std::basic_string, int>' does not satisfy 'range'
590 | concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>;
| ^
/usr/lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13/bits/ranges_base.h:503:2: note: because 'ranges::begin(__t)' would be invalid: no matching function for call to object of type 'const __cust_access::_Begin'
503 | ranges::begin(__t);
| ^
/usr/lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13/bits/ranges_algobase.h:301:7: note: candidate function template not viable: requires 3 arguments, but 2 were provided
301 | operator()(_Iter __first, _Sent __last, _Out __result) const
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

@zyn0217
Copy link
Contributor

zyn0217 commented Oct 5, 2025

@ronlieb Can you provide us with a self-contained example?

@zyn0217
Copy link
Contributor

zyn0217 commented Oct 5, 2025

@DKLoehr Thanks, can you please test with #161994?

zyn0217 added a commit that referenced this pull request Oct 5, 2025
This expression is not handled by default in RAV, so our parameter
mapping and cache mechanism don't work when it appears in a template
argument list.

There are a few other expressions, such as PackIndexingExpr and
FunctionParmPackExpr, which are also no-ops by default. I don't have a
test case for them now, so let's leave those until users complain :/

There was also a bug in updating the parameter mapping, where the
AssociatedDecl was not updated accordingly.

Also also, this fixes another regression reported in
#161671 (comment),
where we failed to account for the variable initializer in cache
profiling.

Relies on #161671

Fixes #161983
Fixes #161987
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Oct 5, 2025
This expression is not handled by default in RAV, so our parameter
mapping and cache mechanism don't work when it appears in a template
argument list.

There are a few other expressions, such as PackIndexingExpr and
FunctionParmPackExpr, which are also no-ops by default. I don't have a
test case for them now, so let's leave those until users complain :/

There was also a bug in updating the parameter mapping, where the
AssociatedDecl was not updated accordingly.

Also also, this fixes another regression reported in
llvm/llvm-project#161671 (comment),
where we failed to account for the variable initializer in cache
profiling.

Relies on #161671

Fixes llvm/llvm-project#161983
Fixes llvm/llvm-project#161987
searlmc1 pushed a commit to ROCm/llvm-project that referenced this pull request Oct 5, 2025
@cor3ntin
Copy link
Contributor Author

cor3ntin commented Oct 5, 2025

@ronlieb can you try again with trunk ? it should be fixed by 92d8313

It was reproducible with

#include <string>
#include <ranges>
#include <array>
#include <algorithm>

std::array<char, 10> current_thread_name{};
auto test(const std::string& task_name) -> void
{
    // Initialize the task management
    std::ranges::fill(current_thread_name, '\0');
    std::ranges::copy(task_name | std::views::take(10 - 1), current_thread_name.begin());
}

searlmc1 pushed a commit to ROCm/llvm-project that referenced this pull request Oct 5, 2025
…161671)

In the standard, constraint satisfaction checking is done on the
normalized form of a constraint.

Clang instead substitutes on the non-normalized form, which causes us to
report substitution failures in template arguments or concept ids, which
is non-conforming but unavoidable without a parameter mapping

This patch normalizes before satisfaction checking. However, we preserve
concept-id nodes in the normalized form, solely for diagnostics
purposes.

This addresses llvm#61811 and
related concepts conformance bugs, ideally to make the remaining
implementation of concept template parameters easier

Fixes llvm#135190
Fixes llvm#61811

Co-authored-by: Younan Zhang
[[email protected]](mailto:[email protected])

---------

Co-authored-by: Younan Zhang <[email protected]>
@ronlieb
Copy link
Contributor

ronlieb commented Oct 5, 2025

@ronlieb Can you provide us with a self-contained example?

this PR seems to have resolved the issue #161994

aokblast pushed a commit to aokblast/llvm-project that referenced this pull request Oct 6, 2025
This expression is not handled by default in RAV, so our parameter
mapping and cache mechanism don't work when it appears in a template
argument list.

There are a few other expressions, such as PackIndexingExpr and
FunctionParmPackExpr, which are also no-ops by default. I don't have a
test case for them now, so let's leave those until users complain :/

There was also a bug in updating the parameter mapping, where the
AssociatedDecl was not updated accordingly.

Also also, this fixes another regression reported in
llvm#161671 (comment),
where we failed to account for the variable initializer in cache
profiling.

Relies on llvm#161671

Fixes llvm#161983
Fixes llvm#161987
@DKLoehr
Copy link
Contributor

DKLoehr commented Oct 6, 2025

@DKLoehr Thanks, can you please test with #161994?

That seems to have fixed it, thanks for the quick response!

@wlei-llvm
Copy link
Contributor

Hey, this breaks our internal range-v3:


In file included from range-v3/range/v3/view/transform.hpp:37:
In file included from range-v3/range/v3/view/adaptor.hpp:28:
In file included from range-v3/range/v3/view/all.hpp:26:
In file included from range-v3/range/v3/view/ref.hpp:25:
range-v3/range/v3/view/interface.hpp:233:59: error: invalid operands to binary
      expression ('detail::facade_sentinel_t<ranges::remove_if_view<ranges::zip_view<ranges::detail::index_view<unsigned long, long>, ranges::ref_view<const
      std::vector<std::shared_ptr<const facebook::crux::SelectItem>, std::allocator<std::shared_ptr<const facebook::crux::SelectItem>>>>>, ranges::logical_negate<(lambda at
      ccr/HqlRenderer.cpp:4523:33)>>>' (aka 'ranges::adaptor_sentinel<ranges::iter_zip_with_view<ranges::detail::indirect_zip_fn_,
      ranges::detail::index_view<unsigned long, long>, ranges::ref_view<const std::vector<std::shared_ptr<const facebook::crux::SelectItem>>>>::sentinel<false>,
      ranges::adaptor_base>') and 'detail::facade_iterator_t<ranges::remove_if_view<ranges::zip_view<ranges::detail::index_view<unsigned long, long>, ranges::ref_view<const
      std::vector<std::shared_ptr<const facebook::crux::SelectItem>, std::allocator<std::shared_ptr<const facebook::crux::SelectItem>>>>>, ranges::logical_negate<(lambda at
      ccr/HqlRenderer.cpp:4523:33)>>>' (aka
      'basic_iterator<ranges::adaptor_cursor<ranges::basic_iterator<ranges::iter_zip_with_view<ranges::detail::indirect_zip_fn_, ranges::detail::index_view<unsigned long, long>,
      ranges::ref_view<const std::vector<std::shared_ptr<const facebook::crux::SelectItem>, std::allocator<std::shared_ptr<const facebook::crux::SelectItem>>>>>::cursor<false>>,
      ranges::remove_if_view<ranges::zip_view<ranges::detail::index_view<unsigned long, long>, ranges::ref_view<const std::vector<std::shared_ptr<const facebook::crux::SelectItem>,
      std::allocator<std::shared_ptr<const facebook::crux::SelectItem>>>>>, ranges::logical_negate<(lambda at ccr/HqlRenderer.cpp:4523:33)>>::adaptor>>'))
  233 |             return static_cast<size_type>(derived().end() - derived().begin());
      |                                           ~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~
range-v3/range/v3/range/primitives.hpp:134:35: note: in instantiation of
      function template specialization 'ranges::view_interface<ranges::remove_if_view<ranges::zip_view<ranges::detail::index_view<unsigned long, long>, ranges::ref_view<const
      std::vector<std::shared_ptr<const facebook::crux::SelectItem>>>>, ranges::logical_negate<(lambda at ccr/HqlRenderer.cpp:4523:33)>>>::size<true>' requested here
  134 |                 return ((R &&) r).size();
      |                                   ^
range-v3/range/v3/view/transform.hpp:189:20: note: in instantiation of function
      template specialization 'ranges::_size_::fn::operator()<ranges::filter_view<ranges::zip_view<ranges::detail::index_view<unsigned long, long>, ranges::ref_view<const
      std::vector<std::shared_ptr<const facebook::crux::SelectItem>>>>, (lambda at ccr/HqlRenderer.cpp:4523:33)> &>' requested here
  189 |             return ::ranges::size(this->base());
      |                    ^
range-v3/range/v3/range/primitives.hpp:52:28: note: in instantiation of member
      function 'ranges::iter_transform_view<ranges::filter_view<ranges::zip_view<ranges::detail::index_view<unsigned long, long>, ranges::ref_view<const
      std::vector<std::shared_ptr<const facebook::crux::SelectItem>>>>, (lambda at ccr/HqlRenderer.cpp:4523:33)>, ranges::indirected<(lambda at
      ccr/HqlRenderer.cpp:4528:36)>>::size' requested here
   52 |                 ((T &&) t).size()
      |                            ^
range-v3/concepts/concepts/concepts.hpp:464:35: note: expanded from macro
      'CPP_requires'
  464 |         CPP_PP_CAT(CPP_REQUIRES_, REQS)
      |                                   ^
range-v3/concepts/concepts/concepts.hpp:67:45: note: expanded from macro
      'CPP_PP_CAT'
   67 | #define CPP_PP_CAT(X, ...)   CPP_PP_CAT_(X, __VA_ARGS__)
      |                                             ^
range-v3/concepts/concepts/concepts.hpp:66:35: note: expanded from macro
      'CPP_PP_CAT_'
   66 | #define CPP_PP_CAT_(X, ...)  X ## __VA_ARGS__
      |                                   ^
range-v3/concepts//concepts/concepts.hpp:475:7: note: expanded from macro
      'CPP_REQUIRES_AUX_'
  475 |     { __VA_ARGS__; }
      |       ^
range-v3/range/v3/range/primitives.hpp:52:17: note: in instantiation of
      requirement here
   52 |                 ((T &&) t).size()
      |                 ^~~~~~~~~~~~~~~~~
range-v3/concepts/concepts/concepts.hpp:464:35: note: expanded from macro
      'CPP_requires'
  464 |         CPP_PP_CAT(CPP_REQUIRES_, REQS)
      |                                   ^~~~
range-v3/concepts/concepts/concepts.hpp:67:45: note: expanded from macro
      'CPP_PP_CAT'
   67 | #define CPP_PP_CAT(X, ...)   CPP_PP_CAT_(X, __VA_ARGS__)
      |                                             ^~~~~~~~~~~
range-v3/concepts/concepts/concepts.hpp:66:35: note: expanded from macro
      'CPP_PP_CAT_'
   66 | #define CPP_PP_CAT_(X, ...)  X ## __VA_ARGS__
      |                                   ^~~~~~~~~~~
range-v3/concepts/concepts/concepts.hpp:475:7: note: expanded from macro
      'CPP_REQUIRES_AUX_'
  475 |     { __VA_ARGS__; }
      |       ^~~~~~~~~~~
range-v3/range/v3/range/primitives.hpp:49:9: note: while substituting template
      arguments into constraint expression here
   49 |         CPP_requires(has_member_size_,
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   50 |             requires(T && t) //
      |             ~~~~~~~~~~~~~~~~~~~
   51 |             (
      |             ~
   52 |                 ((T &&) t).size()
      |                 ~~~~~~~~~~~~~~~~~
   53 |             ));
      |             ~~
range-v3/concepts/concepts/concepts.hpp:464:9: note: expanded from macro
      'CPP_requires'
  464 |         CPP_PP_CAT(CPP_REQUIRES_, REQS)
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
range-v3/concepts/concepts/concepts.hpp:67:30: note: expanded from macro
      'CPP_PP_CAT'
   67 | #define CPP_PP_CAT(X, ...)   CPP_PP_CAT_(X, __VA_ARGS__)
      |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~
range-v3/concepts/concepts/concepts.hpp:66:30: note: expanded from macro
      'CPP_PP_CAT_'
   66 | #define CPP_PP_CAT_(X, ...)  X ## __VA_ARGS__
      |                              ^~~~~~~~~~~~~~~~
<scratch space>:23:1: note: expanded from here
   23 | CPP_REQUIRES_requires
      | ^
range-v3/concepts/concepts/concepts.hpp:471:5: note: expanded from macro
      'CPP_REQUIRES_requires'
  471 |     requires(__VA_ARGS__) CPP_REQUIRES_AUX_
      |     ^
range-v3/range/v3/range/primitives.hpp:58:30: note: (skipping 5 contexts in
      backtrace; use -ftemplate-backtrace-limit=0 to see all)
   58 |             CPP_requires_ref(_size_::has_member_size_, T);
      |                              ^
range-v3/range/v3/range/concepts.hpp:194:5: note: while substituting template
      arguments into constraint expression here
  194 |     CPP_requires(sized_range_,
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~
  195 |         requires(T & t) //
      |         ~~~~~~~~~~~~~~~~~~
  196 |         (
      |         ~
  197 |             ::ranges::size(t)
      |             ~~~~~~~~~~~~~~~~~
  198 |         ));
      |         ~~
range-v3/concepts/concepts/concepts.hpp:464:9: note: expanded from macro
      'CPP_requires'
  464 |         CPP_PP_CAT(CPP_REQUIRES_, REQS)
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
range-v3/concepts/concepts/concepts.hpp:67:30: note: expanded from macro
      'CPP_PP_CAT'
   67 | #define CPP_PP_CAT(X, ...)   CPP_PP_CAT_(X, __VA_ARGS__)
      |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~
range-v3/concepts/concepts/concepts.hpp:66:30: note: expanded from macro
      'CPP_PP_CAT_'
   66 | #define CPP_PP_CAT_(X, ...)  X ## __VA_ARGS__
      |                              ^~~~~~~~~~~~~~~~
<scratch space>:176:1: note: expanded from here
  176 | CPP_REQUIRES_requires
      | ^
range-v3/concepts/concepts/concepts.hpp:471:5: note: expanded from macro
      'CPP_REQUIRES_requires'
  471 |     requires(__VA_ARGS__) CPP_REQUIRES_AUX_
      |     ^
range-v3/range/v3/range/concepts.hpp:211:26: note: while checking the
      satisfaction of concept 'sized_range_requires_<cont_t, iter_t, ranges::transform_view<ranges::filter_view<ranges::zip_view<ranges::detail::index_view<unsigned long, long>,
      ranges::ref_view<const std::vector<std::shared_ptr<const facebook::crux::SelectItem>>>>, (lambda at ccr/HqlRenderer.cpp:4523:33)>,
      (lambda at ccr/HqlRenderer.cpp:4528:36)>>' requested here
  211 |         CPP_requires_ref(::ranges::sized_range_, T) &&
      |         ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
range-v3/concepts/concepts/concepts.hpp:466:16: note: expanded from macro
      'CPP_requires_ref'
  466 |     CPP_PP_CAT(NAME, requires_)<__VA_ARGS__>
      |     ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
range-v3/concepts/concepts/concepts.hpp:67:42: note: expanded from macro
      'CPP_PP_CAT'
   67 | #define CPP_PP_CAT(X, ...)   CPP_PP_CAT_(X, __VA_ARGS__)
      |                                          ^
range-v3/concepts/concepts/concepts.hpp:66:30: note: expanded from macro
      'CPP_PP_CAT_'
   66 | #define CPP_PP_CAT_(X, ...)  X ## __VA_ARGS__
      |                              ^
range-v3/range/v3/range/conversion.hpp:261:13: note: while checking the
      satisfaction of concept 'sized_range<cont_t, iter_t, ranges::transform_view<ranges::filter_view<ranges::zip_view<ranges::detail::index_view<unsigned long, long>,
      ranges::ref_view<const std::vector<std::shared_ptr<const facebook::crux::SelectItem>>>>, (lambda at ccr/HqlRenderer.cpp:4523:33)>,
      (lambda at ccr/HqlRenderer.cpp:4528:36)>>' requested here
  261 |             sized_range<R>;
      |             ^~~~~~~~~~~~~~
range-v3/range/v3/range/conversion.hpp:345:39: note: while checking the
      satisfaction of concept 'to_container_reserve<cont_t, iter_t, ranges::transform_view<ranges::filter_view<ranges::zip_view<ranges::detail::index_view<unsigned long, long>,
      ranges::ref_view<const std::vector<std::shared_ptr<const facebook::crux::SelectItem>>>>, (lambda at ccr/HqlRenderer.cpp:4523:33)>,
      (lambda at ccr/HqlRenderer.cpp:4528:36)>>' requested here
  345 |                     meta::bool_<(bool)to_container_reserve<cont_t, iter_t, Rng>>;
      |                                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
range-v3/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::transform_view<ranges::filter_view<ranges::zip_view<ranges::detail::index_view<unsigned
      long, long>, ranges::ref_view<const std::vector<std::shared_ptr<const facebook::crux::SelectItem>>>>, (lambda at ccr/HqlRenderer.cpp:4523:33)>,
      (lambda at ccr/HqlRenderer.cpp:4528:36)>>' requested here
  276 |                 return static_cast<Fn &&>(fn)(static_cast<Rng &&>(rng));
      |                        ^
range-v3/range/v3/iterator/basic_iterator.hpp:803:5: note: candidate template
      ignored: could not match 'basic_iterator' against 'ranges::adaptor_sentinel'
  803 |     operator-(basic_iterator<Cur> left, typename basic_iterator<Cur>::difference_type n)
      |     ^
range-v3/range/v3/iterator/basic_iterator.hpp:811:5: note: candidate template
      ignored: could not match 'basic_iterator' against 'ranges::adaptor_sentinel'
  811 |     operator-(basic_iterator<Cur2> const & left, basic_iterator<Cur> const & right)
      |     ^
range-v3/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::zip_view<ranges::detail::index_view<unsigned long, long>,
      ranges::ref_view<const std::vector<std::shared_ptr<const facebook::crux::SelectItem>, std::allocator<std::shared_ptr<const facebook::crux::SelectItem>>>>>,
      ranges::logical_negate<(lambda at ccr/HqlRenderer.cpp:4523:33)>>>, Cur =
      ranges::adaptor_cursor<ranges::basic_iterator<ranges::iter_zip_with_view<ranges::detail::indirect_zip_fn_, ranges::detail::index_view<unsigned long, long>,
      ranges::ref_view<const std::vector<std::shared_ptr<const facebook::crux::SelectItem>>>>::cursor<false>>,
      ranges::remove_if_view<ranges::zip_view<ranges::detail::index_view<unsigned long, long>, ranges::ref_view<const std::vector<std::shared_ptr<const
      facebook::crux::SelectItem>>>>, ranges::logical_negate<(lambda at ccr/HqlRenderer.cpp:4523:33)>>::adaptor>]
  819 |     operator-(S const & left, basic_iterator<Cur> const & right)
      |     ^
range-v3/range/v3/iterator/basic_iterator.hpp:817:18: note: because
      'detail::sized_sentinel_for_cursor<detail::facade_sentinel_t<ranges::remove_if_view<ranges::zip_view<ranges::detail::index_view<unsigned long, long>, ranges::ref_view<const
      std::vector<std::shared_ptr<const facebook::crux::SelectItem>, std::allocator<std::shared_ptr<const facebook::crux::SelectItem> > > > >, ranges::logical_negate<(lambda at
      ccr/HqlRenderer.cpp:4523:33)> > >, ranges::adaptor_cursor<ranges::basic_iterator<ranges::iter_zip_with_view<ranges::detail::indirect_zip_fn_,
      ranges::detail::index_view<unsigned long, long>, ranges::ref_view<const std::vector<std::shared_ptr<const facebook::crux::SelectItem> > > >::cursor<false> >,
      ranges::remove_if_view<ranges::zip_view<ranges::detail::index_view<unsigned long, long>, ranges::ref_view<const std::vector<std::shared_ptr<const facebook::crux::SelectItem> >
      > >, ranges::logical_negate<(lambda at ccr/HqlRenderer.cpp:4523:33)> >::adaptor>>' evaluated to false
  817 |         requires detail::sized_sentinel_for_cursor<S, Cur>)
      |                  ^
range-v3/range/v3/detail/prologue.hpp:35:26: note: expanded
      from macro 'template'
   35 |     template<__VA_ARGS__ CPP_TEMPLATE_AUX_                                      \
      |                          ^
range-v3/range/v3/detail/range_access.hpp:329:30: note: because
      'detail::sized_sentinel_for_cursor_requires_<ranges::adaptor_sentinel<ranges::iter_zip_with_view<ranges::detail::indirect_zip_fn_, ranges::detail::index_view<unsigned long,
      long>, ranges::ref_view<const std::vector<std::shared_ptr<const facebook::crux::SelectItem> > > >::sentinel<false>, ranges::adaptor_base>,
      ranges::adaptor_cursor<ranges::basic_iterator<ranges::iter_zip_with_view<ranges::detail::indirect_zip_fn_, ranges::detail::index_view<unsigned long, long>,
      ranges::ref_view<const std::vector<std::shared_ptr<const facebook::crux::SelectItem> > > >::cursor<false> >,
      ranges::remove_if_view<ranges::zip_view<ranges::detail::index_view<unsigned long, long>, ranges::ref_view<const std::vector<std::shared_ptr<const facebook::crux::SelectItem> >
      > >, ranges::logical_negate<(lambda at ccr/HqlRenderer.cpp:4523:33)> >::adaptor>>' evaluated to false
  329 |             CPP_requires_ref(detail::sized_sentinel_for_cursor_, S, C);
      |                              ^
range-v3/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/range/v3/iterator/basic_iterator.hpp:826:5: note: candidate template
      ignored: could not match 'basic_iterator' against 'ranges::adaptor_sentinel'
  826 |     operator-(basic_iterator<Cur> const & left, S const & right)
      |     ^
range-v3/range/v3/iterator/common_iterator.hpp:290:27: note: candidate template
      ignored: could not match 'common_iterator' against 'ranges::adaptor_sentinel'
  290 |     iter_difference_t<I2> operator-(common_iterator<I1, S1> const & x,
      |                           ^
range-v3/range/v3/iterator/counted_iterator.hpp:377:37: note: candidate template
      ignored: could not match 'counted_iterator' against 'ranges::adaptor_sentinel'
  377 |     constexpr iter_difference_t<I2> operator-(counted_iterator<I1> const & x,
      |                                     ^
range-v3/range/v3/iterator/counted_iterator.hpp:384:36: note: candidate template
      ignored: could not match 'counted_iterator' against 'ranges::adaptor_sentinel'
  384 |     constexpr iter_difference_t<I> operator-(counted_iterator<I> const & x,
      |                                    ^
range-v3/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,
      |            

Seems others hit some related issues too and there are some fixes, but I just checked the error are still present for the HEAD, any idea for the fix?

@zyn0217
Copy link
Contributor

zyn0217 commented Oct 6, 2025

@wlei-llvm We would appreciate it if you can provide us with a self-contained reproducer, otherwise there's nothing we can do.

@wlei-llvm
Copy link
Contributor

@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!

@zyn0217
Copy link
Contributor

zyn0217 commented Oct 7, 2025

@wlei-llvm thanks for your example. I'm running a reduction with it and we'll look into it soon once we have it reduced.

@zyn0217
Copy link
Contributor

zyn0217 commented Oct 7, 2025

@wlei-llvm #162272 should fix it :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Clang considers fold expanded constraint ambiguous when it shouldn't be Clang type substitution for concepts is too eager
5 participants