Created attachment 61452 [details] This code does not compile. The code given in the file does not compile, however, using include instead will cause this code to compile perfectly fine. Weirder is that having the code inside a lambda function instead of a normal function causes the error to go away. This could be an issue with libstdc++, but seems unlikely to me. In the off chance that it was I apologize for tagging it as c++.
This compiles fine on trunk, but errors on 15. I'm not sure what fixed the bug; r16-652-g9694bb129c0dbf seemed likely but reverting it locally didn't cause trunk to error.
Fixed on trunk by r16-504-g3c7c2a6b86da64 "c++: visibility of instantiated template friends", perhaps the fix is suitable for backporting?
Probably not very useful but here's a mechanically reduced testcase (fixed by r16-504): $ cat std.ii module; 16:56 [38/1494] namespace std { template <typename> auto declval() -> decltype(0); template <typename> void forward() {} template <typename, typename> concept convertible_to = requires { declval; }; template <typename _Tp> concept move_constructible = convertible_to<_Tp, _Tp>; namespace ranges { inline namespace _Cpo {} } // namespace ranges namespace __detail { template <typename _Iter> using __iter_concept = _Iter; } template <typename _Iter> concept input_iterator = requires { typename __detail::__iter_concept<_Iter>; }; namespace ranges { namespace _Cpo { int end; } template <typename> concept range = requires { end; }; template <typename _Tp> concept input_range = input_iterator<_Tp>; template <typename _Tp> concept viewable_range = range<_Tp>; } // namespace ranges struct vector {}; namespace ranges { template <typename _Adaptor, typename> concept __adaptor_invocable = requires { declval<_Adaptor>; }; template <typename...> struct _Partial; template <typename _Tp> concept __is_range_adaptor_closure = requires(_Tp __t) { __t; }; template <typename _Self, typename _Range> requires __is_range_adaptor_closure<_Self> && __adaptor_invocable<_Self, _Range> constexpr auto operator|(_Range &&, _Self &&) {} template <typename> struct _RangeAdaptorClosure { template <typename _Self, typename _Range> requires __is_range_adaptor_closure<_Self> && __adaptor_invocable<_Self, _Range> friend constexpr auto operator|(_Range &&, _Self &&); }; struct _RangeAdaptor { template <typename... _Args> auto operator()(_Args...) { return _Partial<int, _Args...>{0, forward<_Args>...}; } }; template <typename _Adaptor, typename _Arg> struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure<_Arg> { template <typename _Tp> _Partial(int, _Tp) {} }; namespace views { _RangeAdaptorClosure<int> all; template <viewable_range> using all_t = decltype(all); } // namespace views template <input_range, move_constructible> class transform_view; template <typename _Range, typename _Fp> transform_view() -> transform_view<views::all_t<_Range>, _Fp>; namespace views { namespace __detail { template <typename, typename> concept __can_transform_view = requires { transform_view(declval); }; } // namespace __detail struct _Transform : _RangeAdaptor { template <viewable_range _Range, typename _Fp> requires __detail::__can_transform_view<_Range, _Fp> auto operator0(); } inline transform; } // namespace views } // namespace ranges } // namespace std export module std; export namespace std { namespace ranges { namespace views { using views::transform; } } // namespace ranges using std::vector; } // namespace std $ cat 120318.C import std; using std::vector; using std::ranges::views::transform; int main(int argl,char**argv) { vector v; v | transform([](int x){return x * x % 24;}); return 0; }
If this is fixed, can I mark as resolved?
Yeah, I'll mark as fixed for now. Perhaps suitable for backporting to 15 but we had a lot of other fixes to 16 regarding temploid friends as well that probably aren't suitable to backporting.