1// RUN: rm -rf %t 2// RUN: mkdir -p %t 3// RUN: split-file %s %t 4// 5// RUN: %clang_cc1 -std=c++23 -emit-module-interface %t/a.cppm -o %t/a.pcm 6// RUN: %clang_cc1 -std=c++23 %t/b.cpp -fmodule-file=a=%t/a.pcm -fsyntax-only -verify 7 8// RUN: %clang_cc1 -std=c++23 -emit-reduced-module-interface %t/a.cppm -o %t/a.pcm 9// RUN: %clang_cc1 -std=c++23 %t/b.cpp -fmodule-file=a=%t/a.pcm -fsyntax-only -verify 10 11//--- foo.h 12class TypeA {}; 13 14template<class _Tp, class _Up> 15concept __comparable = requires (_Tp &&__t, _Up &&__u) { 16 __t == __u; 17}; 18 19namespace ranges { 20namespace __end { 21 template <class _Tp> 22 concept __member_end = 23 requires(_Tp&& __t) { 24 { __t.end() } -> __comparable<TypeA>; 25 }; 26 27 struct __fn { 28 template <class _Tp> 29 requires __member_end<_Tp> 30 constexpr auto operator()(_Tp&& __t) const 31 { 32 return true; 33 } 34 35 void operator()(auto&&) const = delete; 36 }; 37} 38 39inline namespace __cpo { 40 inline constexpr auto end = __end::__fn{}; 41} 42} 43 44template <class _Tp> 45concept range = requires(_Tp& __t) { 46 ranges::end(__t); 47}; 48 49template <class T> 50class a { 51public: 52 a(T*) {} 53 TypeA end() { return {}; } 54}; 55 56template <class T> 57class a_view { 58public: 59 template <class U> 60 a_view(a<U>) {} 61}; 62template <range _Range> 63a_view(_Range) -> a_view<int>; 64 65constexpr bool operator==(TypeA, TypeA) { 66 return true; 67} 68 69//--- a.cppm 70module; 71#include "foo.h" 72export module a; 73export using ::a; 74export using ::a_view; 75 76// We need to mention the 'operator==' explicitly to make sure it won't be 77// discarded. 78export using ::operator==; 79 80//--- b.cpp 81// expected-no-diagnostics 82import a; 83void use() { 84 auto _ = a{"char"}; 85 auto __ = a_view{_}; 86} 87