-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
Description
We have some third parties integrated via Swift/C++ interop that include boost libraries.
Currently we use swift 6.1 and the code compiles and works. However, trying 6.2 leads to redundant template instantiation and consequent failure.
boost/iterator/detail/facade_iterator_category.hpp:142:5: error: no matching function for call to 'assertion_failed'
134 | //
135 | template <class Category, class Traversal>
136 | struct iterator_category_with_traversal
| `- note: in instantiation of template class 'boost::iterators::detail::iterator_category_with_traversal<std::bidirectional_iterator_tag, boost::iterators::bidirectional_traversal_tag>' requested here
137 | : Category, Traversal
138 | {
:
140 | // convertibility to Traversal is redundant. Should just use the
141 | // Category element in that case.
142 | BOOST_MPL_ASSERT_NOT((
| `- error: no matching function for call to 'assertion_failed'
143 | is_convertible<
144 | typename iterator_category_to_traversal<Category>::type
Interesting part is that clang compiles this code perfectly but on swift code compilation swift compiler fails on some boost template code.
Reproduction
There is an original boost code:
// ./Sources/Boost/boost/iterator/detail/facade_iterator_category.hpp
template <class Category, class Traversal>
struct iterator_category_with_traversal
: Category, Traversal
{
// Make sure this isn't used to build any categories where
// convertibility to Traversal is redundant. Should just use the
// Category element in that case.
BOOST_MPL_ASSERT_NOT((
is_convertible<
typename iterator_category_to_traversal<Category>::type
, Traversal
>)); <---- fails here due to instantiation of `iterator_category_with_traversal`
BOOST_MPL_ASSERT((is_iterator_category<Category>));
BOOST_MPL_ASSERT_NOT((is_iterator_category<Traversal>));
BOOST_MPL_ASSERT_NOT((is_iterator_traversal<Category>));
# if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
BOOST_MPL_ASSERT((is_iterator_traversal<Traversal>));
# endif
};
template <class Traversal, class ValueParam, class Reference>
struct facade_iterator_category_impl
{
BOOST_MPL_ASSERT_NOT((is_iterator_category<Traversal>));
typedef typename iterator_facade_default_category<
Traversal,ValueParam,Reference
>::type category;
typedef typename mpl::if_<
is_same<
Traversal
, typename iterator_category_to_traversal<category>::type
>
, category
, iterator_category_with_traversal<category,Traversal>
>::type type;
};
In my scenario I was able to workaround that by replacing this mpl::if
:
typedef typename mpl::if_<
is_same<
Traversal
, typename iterator_category_to_traversal<category>::type
>
, category
, iterator_category_with_traversal<category,Traversal>
>::type type;
with statically asserting the only first branch (that excludes and and assert only first scenario):
static_assert(std::is_same_v<
Traversal
, typename iterator_category_to_traversal<category>::type>);
using type = category;
That means that other branch must never be instantiated but somehow swift compiler tries to do that.
I was also trying to use std::conditional with no luck. Didn't try newer boost because I third party is using this version and it would be mostly impossible to replace it.
Minimized (not very but as much as possible) and complete reproducing scenario is available at https://github.com/ordo-one/external-reproducers/tree/main/swift/swift-cpp-boost-iterator-build
Expected behavior
Expected behavior that this code compiles.
But maybe more precise thing is that compiler should not instantiate template that is never used.
Environment
$ swiftc --version
Apple Swift version 6.2-dev (LLVM 92e60fa736d5709, Swift eba3593d16ab01c)
Target: arm64-apple-macosx15.0
Build config: +assertions
The primary issue was for pre-compiled libraries on Linux x86_64 with the same compiler version but minimized sample was prepared for macOS with the same result.
$ swift --version
Swift version 6.2-dev (LLVM 92e60fa736d5709, Swift eba3593d16ab01c)
Target: x86_64-unknown-linux-gnu
Build config: +assertions
Additional information
Note that sample project includes binary artifact for boost filesystem 1.78.0 which is only needed for linking phase when the project compile with 6.1.2.
For reproducing the issue this artifact is not needed and can be removed from project.