[all-commits] [llvm/llvm-project] 8ad364: [libc++] [ranges] Remove the static_assert from ra...

Quuxplusone via All-commits all-commits at lists.llvm.org
Wed Dec 22 07:37:28 PST 2021

  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 8ad364ad2123af98f24050417710f975b8816a90
  Author: Arthur O'Dwyer <arthur.j.odwyer at gmail.com>
  Date:   2021-12-22 (Wed, 22 Dec 2021)

  Changed paths:
    M libcxx/include/__ranges/access.h
    A libcxx/test/libcxx/ranges/range.access/begin.incomplete_type.sh.cpp
    A libcxx/test/libcxx/ranges/range.access/end.incomplete_type.pass.cpp
    R libcxx/test/libcxx/ranges/range.access/range.access.begin/incomplete.verify.cpp
    R libcxx/test/libcxx/ranges/range.access/range.access.cbegin/incomplete.verify.cpp
    R libcxx/test/libcxx/ranges/range.access/range.access.cend/incomplete.verify.cpp
    R libcxx/test/libcxx/ranges/range.access/range.access.end/incomplete.verify.cpp
    R libcxx/test/libcxx/ranges/range.access/range.prim/data.incomplete.verify.cpp
    R libcxx/test/libcxx/ranges/range.access/range.prim/empty.incomplete.verify.cpp
    M libcxx/test/std/ranges/range.access/range.access.begin/begin.pass.cpp
    M libcxx/test/std/ranges/range.access/range.access.end/end.pass.cpp
    M libcxx/test/std/ranges/range.access/range.prim/empty.pass.cpp
    M libcxx/test/std/ranges/range.access/range.prim/size.pass.cpp

  Log Message:
  [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

More information about the All-commits mailing list