1 // RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
4 template <class Promise
= void> struct coroutine_handle
{
5 coroutine_handle() = default;
6 static coroutine_handle
from_address(void *) noexcept
;
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
;
16 template <class... Args
>
20 template <class... Args
>
21 using void_t
= typename void_t_imp
<Args
...>::type
;
23 template <class T
, class = void>
24 struct traits_sfinae_base
{};
27 struct traits_sfinae_base
<T
, void_t
<typename
T::promise_type
>> {
28 using promise_type
= typename
T::promise_type
;
31 template <class Ret
, class... Args
>
32 struct coroutine_traits
: public traits_sfinae_base
<Ret
> {};
35 struct suspend_never
{
36 bool await_ready() noexcept
;
37 void await_suspend(std::coroutine_handle
<>) noexcept
;
38 void await_resume() noexcept
;
43 MoveOnly(const MoveOnly
&) = delete;
44 MoveOnly(MoveOnly
&&) = default;
48 NoCopyNoMove() = default;
49 NoCopyNoMove(const NoCopyNoMove
&) = delete;
55 auto initial_suspend() { return suspend_never
{}; }
56 auto final_suspend() noexcept
{ return suspend_never
{}; }
57 auto get_return_object() { return task
{}; }
58 static void unhandled_exception() {}
59 void return_value(T
&&value
) {} // expected-note 4{{passing argument}}
63 task
<NoCopyNoMove
> local2val() {
68 task
<NoCopyNoMove
&> local2ref() {
70 co_return value
; // expected-error {{non-const lvalue reference to type 'NoCopyNoMove' cannot bind to a temporary of type 'NoCopyNoMove'}}
73 // We need the move constructor for construction of the coroutine.
74 task
<MoveOnly
> param2val(MoveOnly value
) {
78 task
<NoCopyNoMove
> lvalue2val(NoCopyNoMove
&value
) {
79 co_return value
; // expected-error {{rvalue reference to type 'NoCopyNoMove' cannot bind to lvalue of type 'NoCopyNoMove'}}
82 task
<NoCopyNoMove
> rvalue2val(NoCopyNoMove
&&value
) {
86 task
<NoCopyNoMove
&> lvalue2ref(NoCopyNoMove
&value
) {
90 task
<NoCopyNoMove
&> rvalue2ref(NoCopyNoMove
&&value
) {
91 co_return value
; // expected-error {{non-const lvalue reference to type 'NoCopyNoMove' cannot bind to a temporary of type 'NoCopyNoMove'}}
95 operator MoveOnly() &&;
97 task
<MoveOnly
> conversion_operator() {
105 task
<Construct
> converting_constructor() {
110 struct Derived
: MoveOnly
{};
111 task
<MoveOnly
> derived2base() {
117 task
<RetThis
> foo() && {
118 co_return
*this; // expected-error {{rvalue reference to type 'RetThis' cannot bind to lvalue of type 'RetThis'}}
122 template <typename
, typename
>
123 struct is_same
{ static constexpr bool value
= false; };
125 template <typename T
>
126 struct is_same
<T
, T
> { static constexpr bool value
= true; };
128 template <typename T
>
129 struct generic_task
{
130 struct promise_type
{
131 auto initial_suspend() { return suspend_never
{}; }
132 auto final_suspend() noexcept
{ return suspend_never
{}; }
133 auto get_return_object() { return generic_task
{}; }
134 static void unhandled_exception();
135 template <typename U
>
136 void return_value(U
&&value
) {
137 static_assert(is_same
<T
, U
>::value
);
142 generic_task
<MoveOnly
> param2template(MoveOnly value
) {
143 co_return value
; // We should deduce U = MoveOnly.
146 generic_task
<NoCopyNoMove
&> lvalue2template(NoCopyNoMove
&value
) {
147 co_return value
; // We should deduce U = NoCopyNoMove&.