xref: /llvm-project/clang/test/Modules/pr62589.cppm (revision f21ead06750b670cf8ce72d6666e3550b04056a2)
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