-
Notifications
You must be signed in to change notification settings - Fork 15.3k
Open
Labels
clang:frontendLanguage frontend issues, e.g. anything involving "Sema"Language frontend issues, e.g. anything involving "Sema"clang:modulesC++20 modules and Clang Header ModulesC++20 modules and Clang Header Modulesneeds-reductionLarge reproducer that should be reduced into a simpler formLarge reproducer that should be reduced into a simpler formrejects-valid
Description
Consider (https://godbolt.org/z/97rdzMq58):
// a.ccm
module;
#include <ranges>
#include <vector>
export module A;
export std::vector<int> vec;
export auto bar() {
return vec | std::views::transform([](auto& s) -> int& { return s; });
}
// b.ccm
module;
#include <ranges>
#include <vector>
export module B;
import A;
// Identical to 'bar()' above.
auto bar2() {
return vec | std::views::transform([](auto& s) -> int& { return s; });
}
void foo() {
bar2() | std::views::transform([](auto s) { return s; }); // Ok.
bar() | std::views::transform([](auto s) { return s; }); // Error?
}In foo() in module B, we call bar(), which is imported from module A and returns a transform view that is passed a lambda. Attempting to pipe that to another transform view fails, even though it works just fine if we define the function in the same module as foo
/opt/compiler-explorer/clang-assertions-trunk/bin/clang++ --gcc-toolchain=/opt/compiler-explorer/gcc-snapshot -fcolor-diagnostics -fno-crash-diagnostics -std=c++26 -isystem/opt/compiler-explorer/libs/fmt/7.1.3/include -O2 -g -DNDEBUG -std=c++26 -MD -MT CMakeFiles/bug.dir/b.ccm.o -MF CMakeFiles/bug.dir/b.ccm.o.d @CMakeFiles/bug.dir/b.ccm.o.modmap -o CMakeFiles/bug.dir/b.ccm.o -c /app/b.ccm
In module 'A' imported from /app/b.ccm:5:
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/ranges:224:2: error: no matching constructor for initialization of '(lambda at /app/a.ccm:8:40)'
224 | __box(__box&&) = default;
| ^~~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/ranges:1871:11: note: in defaulted move constructor for 'std::ranges::__detail::__box<(lambda at /app/a.ccm:8:40)>' first required here
1871 | class transform_view : public view_interface<transform_view<_Vp, _Fp>>
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/ranges:1431:13: note: in implicit move constructor for 'std::ranges::transform_view<std::ranges::ref_view<std::vector<int>>, (lambda at /app/a.ccm:8:40)>' first required here
1431 | return std::forward<_Range>(__r);
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/ranges:1444:30: note: in instantiation of function template specialization 'std::ranges::views::_All::operator()<std::ranges::transform_view<std::ranges::ref_view<std::vector<int>>, (lambda at /app/a.ccm:8:40)>>' requested here
1444 | using all_t = decltype(all(std::declval<_Range>()));
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/ranges:2221:60: note: in instantiation of template type alias 'all_t' requested here
2221 | transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/ranges:2229:17: note: while substituting deduced template arguments into function template '<deduction guide for transform_view>' [with _Range = std::ranges::transform_view<std::ranges::ref_view<std::vector<int>>, (lambda at /app/a.ccm:8:40)>, _Fp = (lambda at /app/b.ccm:17:35)]
2229 | = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
| ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/ranges:2229:17: note: (skipping 13 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/ranges:931:9: note: while substituting template arguments into constraint expression here
931 | = requires { std::declval<_Adaptor>()(declval<_Args>()...); };
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/ranges:969:10: note: while checking the satisfaction of concept '__adaptor_invocable<std::ranges::views::__adaptor::_Partial<std::ranges::views::_Transform, (lambda at /app/b.ccm:17:35)>, std::ranges::transform_view<std::ranges::ref_view<std::vector<int>>, (lambda at /app/a.ccm:8:40)>>' requested here
969 | && __adaptor_invocable<_Self, _Range>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/ranges:969:10: note: while substituting template arguments into constraint expression here
969 | && __adaptor_invocable<_Self, _Range>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
b.ccm:17:11: note: while checking constraint satisfaction for template 'operator|<std::ranges::views::__adaptor::_Partial<std::ranges::views::_Transform, (lambda at /app/b.ccm:17:35)>, std::ranges::transform_view<std::ranges::ref_view<std::vector<int>>, (lambda at /app/a.ccm:8:40)>>' required here
17 | bar() | std::views::transform([](auto s) { return s; });
| ^
b.ccm:17:11: note: in instantiation of function template specialization 'std::ranges::views::__adaptor::operator|<std::ranges::views::__adaptor::_Partial<std::ranges::views::_Transform, (lambda at /app/b.ccm:17:35)>, std::ranges::transform_view<std::ranges::ref_view<std::vector<int>>, (lambda at /app/a.ccm:8:40)>>' requested here
a.ccm:8:40: note: candidate template ignored: could not match 'auto (*)(auto &) -> int &' against '(lambda at /app/a.ccm:8:40)'
8 | return vec | std::views::transform([](auto& s) -> int& { return s; });
| ^We seem to be failing to... construct a lambda that has no captures, which is weird. Considering that the problem also goes away if I pass e.g. std::identity{} to transform in bar(), this feels like it’s just #110401 all over again, but this time we’re failing to find the right constructor.
I might look into that later today or tomorrow if I can find the time.
CC @ChuanqiXu9
Metadata
Metadata
Assignees
Labels
clang:frontendLanguage frontend issues, e.g. anything involving "Sema"Language frontend issues, e.g. anything involving "Sema"clang:modulesC++20 modules and Clang Header ModulesC++20 modules and Clang Header Modulesneeds-reductionLarge reproducer that should be reduced into a simpler formLarge reproducer that should be reduced into a simpler formrejects-valid