1 // RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -stdlib=libc++ -std=c++1z -fcoroutines-ts -fsyntax-only
2 
3 namespace std::experimental {
4 template <class Promise = void> struct coroutine_handle {
5   coroutine_handle() = default;
6   static coroutine_handle from_address(void *) noexcept;
7 };
8 
9 template <> struct coroutine_handle<void> {
10   static coroutine_handle from_address(void *) noexcept;
11   coroutine_handle() = default;
12   template <class PromiseType>
13   coroutine_handle(coroutine_handle<PromiseType>) noexcept;
14 };
15 
16 template <class... Args>
17 struct void_t_imp {
18   using type = void;
19 };
20 template <class... Args>
21 using void_t = typename void_t_imp<Args...>::type;
22 
23 template <class T, class = void>
24 struct traits_sfinae_base {};
25 
26 template <class T>
27 struct traits_sfinae_base<T, void_t<typename T::promise_type>> {
28   using promise_type = typename T::promise_type;
29 };
30 
31 template <class Ret, class... Args>
32 struct coroutine_traits : public traits_sfinae_base<Ret> {};
33 }
34 
35 struct suspend_never {
36   bool await_ready() noexcept;
37   void await_suspend(std::experimental::coroutine_handle<>) noexcept;
38   void await_resume() noexcept;
39 };
40 
41 struct MoveOnly {
MoveOnlyMoveOnly42   MoveOnly() {};
43   MoveOnly(const MoveOnly&) = delete;
MoveOnlyMoveOnly44   MoveOnly(MoveOnly&&) noexcept {};
~MoveOnlyMoveOnly45   ~MoveOnly() {};
46 };
47 
48 template <typename T>
49 struct task {
50   struct promise_type {
initial_suspendtask::promise_type51     auto initial_suspend() { return suspend_never{}; }
final_suspendtask::promise_type52     auto final_suspend() noexcept { return suspend_never{}; }
get_return_objecttask::promise_type53     auto get_return_object() { return task{}; }
unhandled_exceptiontask::promise_type54     static void unhandled_exception() {}
return_valuetask::promise_type55     void return_value(T&& value) {}
56   };
57 };
58 
f()59 task<MoveOnly> f() {
60   MoveOnly value;
61   co_return value;
62 }
63 
main()64 int main() {
65   f();
66   return 0;
67 }
68 
69 // expected-no-diagnostics
70