[libc++] [ranges] Remove the static_assert from ranges::begin and ranges::end.
authorArthur O'Dwyer <arthur.j.odwyer@gmail.com>
Thu, 16 Dec 2021 03:10:34 +0000 (22:10 -0500)
committerArthur O'Dwyer <arthur.j.odwyer@gmail.com>
Wed, 22 Dec 2021 15:33:17 +0000 (10:33 -0500)
commit8ad364ad2123af98f24050417710f975b8816a90
treee8b394e8c91a315266680c36368116c3f0285afe
parent9075009d1fd5f2bf9aa6c2f362d2993691a316b3
[libc++] [ranges] Remove the static_assert from ranges::begin and ranges::end.

As discussed with ldionne. The problem with this static_assert
is that it makes ranges::begin a pitfall for anyone ever to use
inside a constraint or decltype. Many Ranges things, such as ranges::size,
are specified as "Does X if X is well-formed, or else Y if Y is well-formed,
or else `ranges::end(t) - ranges::begin(t)` if that is well-formed, or else..."
And if there's a static_assert hidden inside `ranges::begin(t)`, then you get
a hard error as soon as you ask the question -- even if the answer would have
been "no, that's not well-formed"!

Constraining on `requires { t + 0; }` or `requires { t + N; }` is verboten
because of https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103700 . For ranges::begin,
we can just decay to a pointer even in the incomplete-type case. For ranges::end,
we can safely constrain on `sizeof(*t)`. Yes, this means that an array of incomplete
type has a `ranges::begin` but no `ranges::end`... just like an unbounded array of
complete type. This is a valid manifestation of IFNDR.

All of the new libcxx/test/std/ cases are mandatory behavior, as far as I'm aware.
Tests for the IFNDR cases in ranges::begin and ranges::end remain in `libcxx/test/libcxx/`.
The similar tests for ranges::empty and ranges::data were simply wrong, AFAIK.

Differential Revision: https://reviews.llvm.org/D115838
13 files changed:
libcxx/include/__ranges/access.h
libcxx/test/libcxx/ranges/range.access/begin.incomplete_type.sh.cpp [new file with mode: 0644]
libcxx/test/libcxx/ranges/range.access/end.incomplete_type.pass.cpp [new file with mode: 0644]
libcxx/test/libcxx/ranges/range.access/range.access.begin/incomplete.verify.cpp [deleted file]
libcxx/test/libcxx/ranges/range.access/range.access.cbegin/incomplete.verify.cpp [deleted file]
libcxx/test/libcxx/ranges/range.access/range.access.cend/incomplete.verify.cpp [deleted file]
libcxx/test/libcxx/ranges/range.access/range.access.end/incomplete.verify.cpp [deleted file]
libcxx/test/libcxx/ranges/range.access/range.prim/data.incomplete.verify.cpp [deleted file]
libcxx/test/libcxx/ranges/range.access/range.prim/empty.incomplete.verify.cpp [deleted file]
libcxx/test/std/ranges/range.access/range.access.begin/begin.pass.cpp
libcxx/test/std/ranges/range.access/range.access.end/end.pass.cpp
libcxx/test/std/ranges/range.access/range.prim/empty.pass.cpp
libcxx/test/std/ranges/range.access/range.prim/size.pass.cpp