ericniebler / range-v3

Range library for C++14/17/20, basis for C++20's std::ranges
Other
4.14k stars 439 forks source link

gcc10 invalid use of incomplete type ‘struct std::tuple_size<std::thread>’ #1430

Closed marehr closed 4 years ago

marehr commented 4 years ago
#include <future> // any include order causes this
#include <range/v3/view/all.hpp>

int main() {
  ranges::cpp20::subrange<std::istreambuf_iterator<char>,
                          std::istreambuf_iterator<char>> sub;

  ranges::cpp20::all_view<decltype(sub)>{sub};
}

https://godbolt.org/z/lfXk-g

In file included from /home/marehr/develope/seqan3/submodules/range-v3/include/meta/meta.hpp:20,
                 from /home/marehr/develope/seqan3/submodules/range-v3/include/range/v3/view/all.hpp:18,
                 from ice.cpp:2:
/home/marehr/develope/seqan3/submodules/range-v3/include/concepts/concepts.hpp: In instantiation of ‘constexpr const bool ranges::detail::pair_like<std::thread>’:
/home/marehr/develope/seqan3/submodules/range-v3/include/range/v3/view/subrange.hpp:159:41:   required from ‘constexpr ranges::subrange<I, S, K>::operator PairLike() const [with PairLike = std::thread; I = std::istreambuf_iterator<char, std::char_traits<char> >; S = std::istreambuf_iterator<char, std::char_traits<char> >; ranges::subrange_kind K = ranges::subrange_kind::unsized]’
/home/marehr/develope/seqan3/submodules/range-v3/include/concepts/swap.hpp:177:22:   required by substitution of ‘template<class T, class U> decltype (concepts::adl_swap_detail::swap(declval<T>(), declval<U>())) concepts::adl_swap_detail::try_adl_swap_(int) [with T = ranges::subrange<std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, ranges::subrange_kind::unsized>&; U = ranges::subrange<std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, ranges::subrange_kind::unsized>&]’
/home/marehr/develope/seqan3/submodules/range-v3/include/concepts/swap.hpp:184:14:   required from ‘constexpr const bool concepts::adl_swap_detail::is_adl_swappable_v<ranges::subrange<std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, ranges::subrange_kind::unsized>&>’
/home/marehr/develope/seqan3/submodules/range-v3/include/concepts/swap.hpp:203:18:   required by substitution of ‘template<class T> constexpr meta::if_c<((! is_adl_swappable_v<T&>) && is_movable_v<T>)> concepts::adl_swap_detail::swap_fn::operator()(T&, T&) const [with T = ranges::subrange<std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, ranges::subrange_kind::unsized>]’
/home/marehr/develope/seqan3/submodules/range-v3/include/concepts/concepts.hpp:1024:13:   required from ‘constexpr auto ranges::views::all_fn::operator()(T&&) const requires  viewable_range<T> [with T = ranges::subrange<std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, ranges::subrange_kind::unsized>]’
/home/marehr/develope/seqan3/submodules/range-v3/include/range/v3/view/all.hpp:92:35:   required by substitution of ‘template<class Rng> using all_t = decltype (ranges::views::all(declval<Rng>())) [with Rng = ranges::subrange<std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, ranges::subrange_kind::unsized>]’
/home/marehr/develope/seqan3/submodules/range-v3/include/range/v3/view/all.hpp:117:19:   required by substitution of ‘template<class Rng>  requires  viewable_range<Rng> using all_view = ranges::views::all_t<Rng> [with Rng = ranges::subrange<std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, ranges::subrange_kind::unsized>]’
ice.cpp:8:40:   required from here
/home/marehr/develope/seqan3/submodules/range-v3/include/meta/meta_fwd.hpp:178:30: error: invalid use of incomplete type ‘struct std::tuple_size<std::thread>’
  178 | #define META_IS_BASE_OF(...) __is_base_of(__VA_ARGS__)
      |                              ^~~~~~~~~~~~~~~~~~~~~~~~~
/home/marehr/develope/seqan3/submodules/range-v3/include/concepts/concepts.hpp:966:13: note: in expansion of macro ‘META_IS_BASE_OF’
  966 |             META_IS_BASE_OF(U, T) &&
      |             ^~~~~~~~~~~~~~~
In file included from /opt/gcc/gcc-git/include/c++/10.0.1/tuple:38,
                 from /opt/gcc/gcc-git/include/c++/10.0.1/mutex:38,
                 from /opt/gcc/gcc-git/include/c++/10.0.1/future:38,
                 from ice.cpp:1:
/opt/gcc/gcc-git/include/c++/10.0.1/utility:84:12: note: declaration of ‘struct std::tuple_size<std::thread>’
   84 |     struct tuple_size;
      |            ^~~~~~~~~~
marehr commented 4 years ago

I reduced it a bit:

#include <iterator>
#include <utility>
namespace ranges {
namespace detail {
template <typename T, typename U>
concept derived_from = __is_base_of(U, T); // works with clang, but fails with gcc
// concept derived_from = requires() { // fails with gcc and clang
//     std::is_base_of<U, T>::value;
//     typename std::is_base_of<U, T>::type;
// };
template <typename T>
concept pair_like =
    derived_from<std::tuple_size<T>, std::integral_constant<std::size_t, 2>>;
} // namespace detail
template <typename I> struct subrange {
  template <detail::pair_like PairLike>
  operator PairLike();
};
} // namespace ranges
template <typename T> concept view_ = requires(T t) { {(t != t)}; };

int main() {
  ranges::subrange<std::istreambuf_iterator<char>>
      sub;
  view_<decltype(sub)>;
}
marehr commented 4 years ago

I think this is a bug, in the sense, that https://en.cppreference.com/w/cpp/types/is_base_of has the signature

template< class Base, class Derived >
struct is_base_of;

with the requirement:

If both Base and Derived are non-union class types, and they are not the same type (ignoring cv-qualification), Derived shall be a complete type; otherwise the behavior is undefined.