[PATCH] D144583: [ADT] Fix definition of `adl_begin`/`adl_end` and `Iter`/`ValueOfRange`
Jakub Kuderski via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 22 13:08:59 PST 2023
kuhar added a comment.
In D144583#4145554 <https://reviews.llvm.org/D144583#4145554>, @dblaikie wrote:
>> Fix adl_begin/adl_end so that they work with incomplete types. These require trailing return types, per. 7.5.2.: > In a trailing-return-type, the class being defined is not required to be complete for purposes of class member access. Class members declared later are not visible.
>
> Not sure I follow here - could you describe this in more detail, why adding a trailing return type helps? What happens if the trailing return type isn't used here?
If you return just `auto`, it fails to compile code like:
template <typename R, typename T = ValueOfRange<R>>
void foo(R&&) { ...
if R is an incomplete type and it cannot lookup the definition of `.begin()` inside `std::begin`.
We rely on this in a few places, e.g., `llvm::interleave` or `mlir::Diagnostic::operator<<`:
class Operation;
...
/// Stream in a range.
template <typename T, typename ValueT = llvm::detail::ValueOfRange<T>>
std::enable_if_t<!std::is_constructible<DiagnosticArgument, T>::value,
Diagnostic &>
operator<<(T &&range) {
return appendRange(range);
}
Error:
/usr/local/google/home/kubak/llvm/llvm-project/llvm/include/llvm/ADT/STLExtras.h:68:10: error: no matching function for call to 'begin'
return begin(container);
^~~~~
/usr/local/google/home/kubak/llvm/llvm-project/llvm/include/llvm/ADT/STLExtras.h:90:39: note: in instantiation of function template specialization 'llvm::adl_begin<c
onst char *&>' requested here
std::remove_reference_t<decltype(*adl_begin(std::declval<RangeT &>()))>;
^
/usr/local/google/home/kubak/llvm/llvm-project/mlir/include/mlir/IR/Diagnostics.h:210:57: note: in instantiation of template type alias 'ValueOfRange' requested here
template <typename T, typename ValueT = llvm::detail::ValueOfRange<T>>
^
/usr/local/google/home/kubak/llvm/llvm-project/mlir/include/mlir/IR/Diagnostics.h:213:3: note: in instantiation of default argument for 'operator<<<const char *&>' r
equired here
operator<<(T &&range) {
^~~~~~~~~~~~~~~~~~~~~~~
/usr/local/google/home/kubak/llvm/llvm-project/mlir/include/mlir/IR/Diagnostics.h:222:65: note: while substituting deduced template arguments into function template
'operator<<' [with T = const char *&, ValueT = (no value)]
c, [this](const auto &a) { *this << a; }, [&]() { *this << delim; });
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/range_access.h:95:5: note: candidate template ignored: could not match '_Tp[_Nm]' against 'co
nst char *'
begin(_Tp (&__arr)[_Nm]) noexcept
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/range_access.h:113:31: note: candidate template ignored: could not match 'valarray<_Tp>' agai
nst 'const char *'
template<typename _Tp> _Tp* begin(valarray<_Tp>&) noexcept;
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/range_access.h:114:37: note: candidate template ignored: could not match 'valarray<_Tp>' agai
nst 'const char *'
template<typename _Tp> const _Tp* begin(const valarray<_Tp>&) noexcept;
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/range_access.h:52:5: note: candidate template ignored: substitution failure [with _Container
= const char *]: member reference base type 'const char *' is not a structure or union
begin(_Container& __cont) -> decltype(__cont.begin())
^ ~
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/range_access.h:63:5: note: candidate template ignored: substitution failure [with _Container
= const char *]: member reference base type 'const char *const' is not a structure or union
begin(const _Container& __cont) -> decltype(__cont.begin())
^ ~
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/initializer_list:90:5: note: candidate template ignored: could not match 'initializer_list<_Tp>' a
gainst 'const char *'
begin(initializer_list<_Tp> __ils) noexcept
I'm not sure how to describe this best.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D144583/new/
https://reviews.llvm.org/D144583
More information about the llvm-commits
mailing list