Quuxplusone / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
https://p1144.godbolt.org/z/jf67zx5hq
Other
0 stars 2 forks source link

Hard error inside `__bounded_iter` implicit conversion #20

Closed Quuxplusone closed 3 days ago

Quuxplusone commented 1 year ago

https://godbolt.org/z/z5E4eMGeW

#define _LIBCPP_ABI_BOUNDED_ITERATORS 1
bool test(std::span<int> s, std::span<const int> cs) {
    auto it = s.begin();
    auto jt = cs.begin();
    static_assert(std::same_as<decltype(it == jt), bool>);
    return (it == jt);
}

The above snippet's static_assert passes, but the next line hard-errors when instantiating the expression (it == jt):

__iterator/bounded_iter.h:63:28: error: '__current_' is a private member of 'std::__bounded_iter<int *>'
   63 |       : __current_(__other.__current_),
      |             

The immediate culprit is that __bounded_iter<T> claims to be implicitly convertible from __bounded_iter<U>:

  template <class _OtherIterator, class = __enable_if_t< is_convertible<_OtherIterator, _Iterator>::value > >
  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bounded_iter(__bounded_iter<_OtherIterator> const& __other) _NOEXCEPT
      : __current_(__other.__current_),
        __begin_(__other.__begin_),
        __end_(__other.__end_) {}

But it probably shouldn't claim to be convertible at all. __bounded_iter should follow exactly the same pattern as __wrap_iter in terms of how it implements its conversions and comparison operators. See "The economist’s $100 bill, and the virtue of consistency" (2022-01-20).

frederick-vs-ja commented 1 week ago

The error itself was fixed by llvm#78929.

But it probably shouldn't claim to be convertible at all.

I think the convertibility issue for __wrap_iter (same for __bounded_iter) has been tracked in llvm#50058. I think that is being fixed now.

Quuxplusone commented 3 days ago

Fixed, thanks @frederick-vs-ja!