Issue 110146
Summary C++20 module error: moving the function into module causes the wrong template instantiation
Labels new issue
Assignees
Reporter stripe2933
    Following code works with Clang 19 + libc++.

`main.cpp`
```c++
import std;

#define FWD(...) static_cast<decltype(__VA_ARGS__)&&>(__VA_ARGS__)

namespace ranges::views {
    constexpr auto deref = std::views::transform([](auto &&x) { return *FWD(x); });
}

int main() {
    auto opts = { std::optional { 1 }, std::optional { 2 } };
    std::println("{}", opts | ranges::views::deref); // [1, 2]
}
```

But this does not:

`main.cpp`
```c++
import std;
import ranges;

int main() {
    auto opts = { std::optional { 1 }, std::optional { 2 } };
 std::println("{}", opts | ranges::views::deref);
}
```

`ranges.cppm`
```c++
export module ranges;

import std;

#define FWD(...) static_cast<decltype(__VA_ARGS__)&&>(__VA_ARGS__)

namespace ranges::views {
    export constexpr auto deref = std::views::transform([](auto &&x) { return *FWD(x); });
}
```

```
====================[ Build | hello | macos-clang-19 ]==========================
/opt/homebrew/Cellar/cmake/3.30.0/bin/cmake --build /Users/stripe2933/Desktop/hello/build/macos-clang-19 --target hello -j 6
[3/4] Building CXX object CMakeFiles/hello.dir/main.cpp.o
FAILED: CMakeFiles/hello.dir/main.cpp.o 
/opt/homebrew/opt/llvm@19/bin/clang++ -nostdinc++ -nostdlib++ -isystem /opt/homebrew/opt/llvm@19/include/c++/v1 -fexperimental-modules-reduced-bmi -std=gnu++23 -arch arm64 -isysroot /Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk -fcolor-diagnostics -MD -MT CMakeFiles/hello.dir/main.cpp.o -MF CMakeFiles/hello.dir/main.cpp.o.d @CMakeFiles/hello.dir/main.cpp.o.modmap -o CMakeFiles/hello.dir/main.cpp.o -c /Users/stripe2933/Desktop/hello/main.cpp
/Users/stripe2933/Desktop/hello/main.cpp:6:29: error: invalid operands to binary _expression_ ('std::initializer_list<std::optional<int>>' (aka 'initializer_list<optional<int>>') and 'const __range_adaptor_closure_t<__bind_back_t<__fn, tuple<(lambda at /Users/stripe2933/Desktop/hello/ranges.cppm:8:57)>>>' (aka 'const std::__1::ranges::__range_adaptor_closure_t<std::__bind_back_t<std::__1::ranges::views::__transform::__fn, std::__1::tuple<ranges::views::(lambda at /Users/stripe2933/Desktop/hello/ranges.cppm:8:57)>>>'))
    6 | std::println("{}", opts | ranges::views::deref);
      | ~~~~ ^ ~~~~~~~~~~~~~~~~~~~~
/opt/homebrew/opt/llvm@19/include/c++/v1/cstddef:73:45: note: candidate function not viable: no known conversion from 'std::initializer_list<std::optional<int>>' (aka 'initializer_list<optional<int>>') to 'byte' for 1st argument
   73 | _LIBCPP_HIDE_FROM_ABI inline constexpr byte operator|(byte __lhs, byte __rhs) noexcept {
      |                                             ^ ~~~~~~~~~~
/opt/homebrew/opt/llvm@19/include/c++/v1/__charconv/chars_format.h:34:53: note: candidate function not viable: no known conversion from 'std::initializer_list<std::optional<int>>' (aka 'initializer_list<optional<int>>') to 'chars_format' for 1st argument
 34 | inline _LIBCPP_HIDE_FROM_ABI constexpr chars_format operator|(chars_format __x, chars_format __y) {
      | ^ ~~~~~~~~~~~~~~~~
/opt/homebrew/opt/llvm@19/include/c++/v1/future:431:47: note: candidate function not viable: no known conversion from 'std::initializer_list<std::optional<int>>' (aka 'initializer_list<optional<int>>') to 'launch' for 1st argument
  431 | inline _LIBCPP_HIDE_FROM_ABI constexpr launch operator|(launch __x, launch __y) {
      |                                               ^ ~~~~~~~~~~
/opt/homebrew/opt/llvm@19/include/c++/v1/bitset:932:1: note: candidate template ignored: could not match 'bitset' against 'std::initializer_list'
  932 | operator|(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT {
      | ^
/opt/homebrew/opt/llvm@19/include/c++/v1/__ranges/range_adaptor.h:71:1: note: candidate template ignored: constraints not satisfied [with _Range = std::initializer_list<std::optional<int>> &, _Closure = const __range_adaptor_closure_t<__bind_back_t<__fn, tuple<(lambda at /Users/stripe2933/Desktop/hello/ranges.cppm:8:57)>>> &]
   71 | operator|(_Range&& __range, _Closure&& __closure) noexcept(is_nothrow_invocable_v<_Closure, _Range>) {
      | ^
/opt/homebrew/opt/llvm@19/include/c++/v1/__ranges/range_adaptor.h:69:12: note: because 'invocable<const std::__1::ranges::__range_adaptor_closure_t<std::__bind_back_t<std::__1::ranges::views::__transform::__fn, std::__1::tuple<ranges::views::(lambda at /Users/stripe2933/Desktop/hello/ranges.cppm:8:57)> > > &, std::initializer_list<std::__1::optional<int> > &>' evaluated to false
 69 |   requires invocable<_Closure, _Range>
      | ^
/opt/homebrew/opt/llvm@19/include/c++/v1/__concepts/invocable.h:28:3: note: because 'std::invoke(std::forward<_Fn>(__fn), std::forward<_Args>(__args)...)' would be invalid: no matching function for call to 'invoke'
   28 |   std::invoke(std::forward<_Fn>(__fn), std::forward<_Args>(__args)...); // not required to be equality preserving
      | ^
/opt/homebrew/opt/llvm@19/include/c++/v1/__ranges/range_adaptor.h:77:52: note: candidate template ignored: constraints not satisfied [with _Closure = std::initializer_list<std::optional<int>> &, _OtherClosure = const __range_adaptor_closure_t<__bind_back_t<__fn, tuple<(lambda at /Users/stripe2933/Desktop/hello/ranges.cppm:8:57)>>> &]
   77 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator|(_Closure&& __c1, _OtherClosure&& __c2) noexcept(
      | ^
/opt/homebrew/opt/llvm@19/include/c++/v1/__ranges/range_adaptor.h:75:11: note: because 'std::initializer_list<std::__1::optional<int>> &' does not satisfy '_RangeAdaptorClosure'
   75 | template <_RangeAdaptorClosure _Closure, _RangeAdaptorClosure _OtherClosure>
      | ^
/opt/homebrew/opt/llvm@19/include/c++/v1/__ranges/range_adaptor.h:62:32: note: because '!ranges::range<remove_cvref_t<initializer_list<optional<int> > &> >' evaluated to false
   62 | concept _RangeAdaptorClosure = !ranges::range<remove_cvref_t<_Tp>> && requires {
      | ^
/opt/homebrew/opt/llvm@19/include/c++/v1/valarray:2858:1: note: candidate template ignored: requirement '__is_val_expr<std::initializer_list<std::__1::optional<int>>>::value' was not satisfied [with _Expr1 = std::initializer_list<std::optional<int>>, _Expr2 = __range_adaptor_closure_t<__bind_back_t<__fn, tuple<(lambda at /Users/stripe2933/Desktop/hello/ranges.cppm:8:57)>>>]
 2858 | operator|(const _Expr1& __x, const _Expr2& __y) {
      | ^
/opt/homebrew/opt/llvm@19/include/c++/v1/valarray:2867:1: note: candidate template ignored: requirement '__is_val_expr<std::initializer_list<std::__1::optional<int>>>::value' was not satisfied [with _Expr = std::initializer_list<std::optional<int>>]
 2867 | operator|(const _Expr& __x, const typename _Expr::value_type& __y) {
      | ^
/opt/homebrew/opt/llvm@19/include/c++/v1/valarray:2876:1: note: candidate template ignored: requirement '__is_val_expr<std::__1::ranges::__range_adaptor_closure_t<std::__bind_back_t<std::__1::ranges::views::__transform::__fn, std::__1::tuple<ranges::views::(lambda at /Users/stripe2933/Desktop/hello/ranges.cppm:8:57)>>>>::value' was not satisfied [with _Expr = __range_adaptor_closure_t<__bind_back_t<__fn, tuple<(lambda at /Users/stripe2933/Desktop/hello/ranges.cppm:8:57)>>>]
 2876 | operator|(const typename _Expr::value_type& __x, const _Expr& __y) {
      | ^
1 error generated.
ninja: build stopped: subcommand failed.
```

Even if I removed `-fexperimental-modules-reduced-bmi` argument, it still throws errors.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to