// This file is the same as coroutines.cpp, except the components are defined in namespace std::experimental.
// The intent of this test is to make sure the std::experimental implementation still works.
// TODO: Remove this test once we drop support for <experimental/coroutine>.

// RUN: %clang_cc1 -std=c++2b                 -fsyntax-only -verify=expected,cxx20_2b,cxx2b    %s -fcxx-exceptions -fexceptions -Wunused-result
// RUN: %clang_cc1 -std=c++20                 -fsyntax-only -verify=expected,cxx14_20,cxx20_2b %s -fcxx-exceptions -fexceptions -Wunused-result
// RUN: %clang_cc1 -std=c++14 -fcoroutines-ts -fsyntax-only -verify=expected,cxx14_20          %s -fcxx-exceptions -fexceptions -Wunused-result

void no_coroutine_traits_bad_arg_await() {
  co_await a; // expected-error {{include <experimental/coroutine>}}
  // expected-error@-1 {{use of undeclared identifier 'a'}}
}

void no_coroutine_traits_bad_arg_yield() {
  co_yield a; // expected-error {{include <experimental/coroutine>}}
  // expected-error@-1 {{use of undeclared identifier 'a'}}
}

void no_coroutine_traits_bad_arg_return() {
  co_return a; // expected-error {{include <experimental/coroutine>}}
  // expected-error@-1 {{use of undeclared identifier 'a'}}
}

void no_coroutine_traits() {
  co_await 4; // expected-error {{std::coroutine_traits type was not found; include <coroutine> before defining a coroutine; include <experimental/coroutine> if your version of libcxx is less than 14.0}}
}

namespace std {
namespace experimental {

template <class... Args>
struct void_t_imp {
  using type = void;
};
template <class... Args>
using void_t = typename void_t_imp<Args...>::type;

template <class T, class = void>
struct traits_sfinae_base {};

template <class T>
struct traits_sfinae_base<T, void_t<typename T::promise_type>> {
  using promise_type = typename T::promise_type;
};

template <class Ret, class... Args>
struct coroutine_traits : public traits_sfinae_base<Ret> {};
// expected-note@-1{{declared here}}
} // namespace experimental
} // namespace std

template <typename Promise> struct coro {};
template <typename Promise, typename... Ps>
struct std::experimental::coroutine_traits<coro<Promise>, Ps...> {
  using promise_type = Promise;
};

struct awaitable {
  bool await_ready() noexcept;
  template <typename F>
  void await_suspend(F) noexcept;
  void await_resume() noexcept;
} a;

struct suspend_always {
  bool await_ready() noexcept { return false; }
  template <typename F>
  void await_suspend(F) noexcept;
  void await_resume() noexcept {}
};

struct suspend_never {
  bool await_ready() noexcept { return true; }
  template <typename F>
  void await_suspend(F) noexcept;
  void await_resume() noexcept {}
};

struct auto_await_suspend {
  bool await_ready();
  template <typename F> auto await_suspend(F) {}
  void await_resume();
};

struct DummyVoidTag {};
DummyVoidTag no_specialization() { // expected-error {{this function cannot be a coroutine: 'std::experimental::coroutine_traits<DummyVoidTag>' has no member named 'promise_type'}}
  co_await a;                      // expected-warning {{support for std::experimental::coroutine_traits will be removed}}
}

template <typename... T>
struct std::experimental::coroutine_traits<int, T...> {};

int no_promise_type() { // expected-error {{this function cannot be a coroutine: 'std::experimental::coroutine_traits<int>' has no member named 'promise_type'}}
  co_await a;
}

int no_promise_type_multiple_awaits(int) { // expected-error {{this function cannot be a coroutine: 'std::experimental::coroutine_traits<int, int>' has no member named 'promise_type'}}
  co_await a;
  co_await a;
}

template <>
struct std::experimental::coroutine_traits<double, double> { typedef int promise_type; };
double bad_promise_type(double) { // expected-error {{this function cannot be a coroutine: 'experimental::coroutine_traits<double, double>::promise_type' (aka 'int') is not a class}}
  co_await a;
}

template <>
struct std::experimental::coroutine_traits<double, int> {
  struct promise_type {};
};
double bad_promise_type_2(int) { // expected-error {{no member named 'initial_suspend'}}
  co_yield 0;                    // expected-error {{no member named 'yield_value' in 'std::experimental::coroutine_traits<double, int>::promise_type'}}
}

struct promise; // expected-note {{forward declaration}}
struct promise_void;
struct void_tag {};
template <typename... T>
struct std::experimental::coroutine_traits<void, T...> { using promise_type = promise; };
template <typename... T>
struct std::experimental::coroutine_traits<void, void_tag, T...> { using promise_type = promise_void; };

// FIXME: This diagnostic is terrible.
void undefined_promise() { // expected-error {{this function cannot be a coroutine: 'experimental::coroutine_traits<void>::promise_type' (aka 'promise') is an incomplete type}}
  co_await a;
}

struct yielded_thing {
  const char *p;
  short a, b;
};

struct not_awaitable {};

struct promise {
  void get_return_object();
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;
  awaitable yield_value(int);           // expected-note 2{{candidate}}
  awaitable yield_value(yielded_thing); // expected-note 2{{candidate}}
  not_awaitable yield_value(void());    // expected-note 2{{candidate}}
  void return_value(int);               // expected-note 2{{here}}
  void unhandled_exception();
};

struct promise_void {
  void get_return_object();
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;
  void return_void();
  void unhandled_exception();
};

void no_coroutine_handle() { // expected-error {{std::coroutine_handle type was not found; include <coroutine> before defining a coroutine; include <experimental/coroutine> if your version of libcxx is less than 14.0}}
  //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
  co_return 5; //expected-note {{function is a coroutine due to use of 'co_return' here}}
}

namespace std {
namespace experimental {
template <class PromiseType = void>
struct coroutine_handle {
  static coroutine_handle from_address(void *) noexcept;
};
template <>
struct coroutine_handle<void> {
  template <class PromiseType>
  coroutine_handle(coroutine_handle<PromiseType>) noexcept;
  static coroutine_handle from_address(void *) noexcept;
};
} // namespace experimental
} // namespace std

void yield() {
  co_yield 0;
  co_yield {"foo", 1, 2};
  co_yield {1e100};                    // expected-error {{cannot be narrowed}} expected-note {{explicit cast}} expected-warning {{implicit conversion}} expected-warning {{braces around scalar}}
  co_yield {"foo", __LONG_LONG_MAX__}; // expected-error {{cannot be narrowed}} expected-note {{explicit cast}} expected-warning {{changes value}}
  co_yield {"foo"};
  co_yield "foo"; // expected-error {{no matching}}
  co_yield 1.0;
  co_yield yield; // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
}

void check_auto_await_suspend() {
  co_await auto_await_suspend{}; // Should compile successfully.
}

void coreturn(int n) {
  co_await a;
  if (n == 0)
    co_return 3;
  if (n == 1)
    co_return {4}; // expected-warning {{braces around scalar initializer}}
  if (n == 2)
    co_return "foo"; // expected-error {{cannot initialize a parameter of type 'int' with an lvalue of type 'const char[4]'}}
  co_return 42;
}

template <class T>
void co_await_non_dependent_arg(T) {
  co_await a;
}
template void co_await_non_dependent_arg(int);

void mixed_yield() {
  co_yield 0; // expected-note {{use of 'co_yield'}}
  return;     // expected-error {{not allowed in coroutine}}
}

void mixed_yield_invalid() {
  co_yield blah; // expected-error {{use of undeclared identifier}}
  // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
  return; // expected-error {{return statement not allowed in coroutine}}
}

template <class T>
void mixed_yield_template(T) {
  co_yield blah; // expected-error {{use of undeclared identifier}}
  // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
  return; // expected-error {{return statement not allowed in coroutine}}
}

template <class T>
void mixed_yield_template2(T) {
  co_yield 42;
  // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
  return; // expected-error {{return statement not allowed in coroutine}}
}

template <class T>
void mixed_yield_template3(T v) {
  co_yield blah(v);
  // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
  return; // expected-error {{return statement not allowed in coroutine}}
}

void mixed_await() {
  co_await a; // expected-note {{use of 'co_await'}}
  return;     // expected-error {{not allowed in coroutine}}
}

void mixed_await_invalid() {
  co_await 42; // expected-error {{'int' is not a structure or union}}
  // expected-note@-1 {{function is a coroutine due to use of 'co_await'}}
  return; // expected-error {{not allowed in coroutine}}
}

template <class T>
void mixed_await_template(T) {
  co_await 42;
  // expected-note@-1 {{function is a coroutine due to use of 'co_await'}}
  return; // expected-error {{not allowed in coroutine}}
}

template <class T>
void mixed_await_template2(T v) {
  co_await v; // expected-error {{'long' is not a structure or union}}
  // expected-note@-1 {{function is a coroutine due to use of 'co_await'}}
  return; // expected-error {{not allowed in coroutine}}
}
template void mixed_await_template2(long); // expected-note {{requested here}}

void only_coreturn(void_tag) {
  co_return; // OK
}

void mixed_coreturn(void_tag, bool b) {
  if (b)
    co_return; // expected-note {{use of 'co_return'}}
  else
    return; // expected-error {{not allowed in coroutine}}
}

void mixed_coreturn_invalid(bool b) {
  if (b)
    co_return; // expected-note {{use of 'co_return'}}
  // expected-error@-1 {{no member named 'return_void' in 'promise'}}
  else
    return; // expected-error {{not allowed in coroutine}}
}

template <class T>
void mixed_coreturn_template(void_tag, bool b, T v) {
  if (b)
    co_return v; // expected-note {{use of 'co_return'}}
  // expected-error@-1 {{no member named 'return_value' in 'promise_void'}}
  else
    return; // expected-error {{not allowed in coroutine}}
}
template void mixed_coreturn_template(void_tag, bool, int); // expected-note {{requested here}}

template <class T>
void mixed_coreturn_template2(bool b, T) {
  if (b)
    co_return v; // expected-note {{use of 'co_return'}}
  // expected-error@-1 {{use of undeclared identifier 'v'}}
  else
    return; // expected-error {{not allowed in coroutine}}
}

struct CtorDtor {
  CtorDtor() {
    co_yield 0; // expected-error {{'co_yield' cannot be used in a constructor}}
  }
  CtorDtor(awaitable a) {
    // The spec doesn't say this is ill-formed, but it must be.
    co_await a; // expected-error {{'co_await' cannot be used in a constructor}}
  }
  ~CtorDtor() {
    co_return 0; // expected-error {{'co_return' cannot be used in a destructor}}
  }
  void operator=(CtorDtor &) {
    co_yield 0; // OK.
  }
  void operator=(CtorDtor const &) {
    co_yield 0; // OK.
  }
  void operator=(CtorDtor &&) {
    co_await a; // OK.
  }
  void operator=(CtorDtor const &&) {
    co_await a; // OK.
  }
  void operator=(int) {
    co_await a; // OK. Not a special member
  }
};

namespace std {
class type_info;
}

void unevaluated() {
  decltype(co_await a); // expected-error {{'co_await' cannot be used in an unevaluated context}}
                        // expected-warning@-1 {{declaration does not declare anything}}
  sizeof(co_await a);   // expected-error {{'co_await' cannot be used in an unevaluated context}}
                        // expected-error@-1 {{invalid application of 'sizeof' to an incomplete type 'void'}}
                        // expected-warning@-2 {{expression with side effects has no effect in an unevaluated context}}
  typeid(co_await a);   // expected-error {{'co_await' cannot be used in an unevaluated context}}
                        // expected-warning@-1 {{expression with side effects has no effect in an unevaluated context}}
                        // expected-warning@-2 {{expression result unused}}
  decltype(co_yield 1); // expected-error {{'co_yield' cannot be used in an unevaluated context}}
                        // expected-warning@-1 {{declaration does not declare anything}}
  sizeof(co_yield 2);   // expected-error {{'co_yield' cannot be used in an unevaluated context}}
                        // expected-error@-1 {{invalid application of 'sizeof' to an incomplete type 'void'}}
                        // expected-warning@-2 {{expression with side effects has no effect in an unevaluated context}}
  typeid(co_yield 3);   // expected-error {{'co_yield' cannot be used in an unevaluated context}}
                        // expected-warning@-1 {{expression with side effects has no effect in an unevaluated context}}
                        // expected-warning@-2 {{expression result unused}}
}

// [expr.await]p2: "An await-expression shall not appear in a default argument."
// FIXME: A better diagnostic would explicitly state that default arguments are
// not allowed. A user may not understand that this is "outside a function."
void default_argument(int arg = co_await 0) {} // expected-error {{'co_await' cannot be used outside a function}}

void await_in_catch_coroutine() {
  try {
  } catch (...) {                   // FIXME: Emit a note diagnostic pointing out the try handler on this line.
    []() -> void { co_await a; }(); // OK
    co_await a;                     // expected-error {{'co_await' cannot be used in the handler of a try block}}
  }
}

void await_nested_in_catch_coroutine() {
  try {
  } catch (...) { // FIXME: Emit a note diagnostic pointing out the try handler on this line.
    try {
      co_await a;                     // expected-error {{'co_await' cannot be used in the handler of a try block}}
      []() -> void { co_await a; }(); // OK
    } catch (...) {
      co_return 123;
    }
  }
}

void await_in_lambda_in_catch_coroutine() {
  try {
  } catch (...) {
    []() -> void { co_await a; }(); // OK
  }
}

void yield_in_catch_coroutine() {
  try {
  } catch (...) {
    co_yield 1; // expected-error {{'co_yield' cannot be used in the handler of a try block}}
  }
}

void return_in_catch_coroutine() {
  try {
  } catch (...) {
    co_return 123; // OK
  }
}

constexpr auto constexpr_deduced_return_coroutine() {
  co_yield 0; // expected-error {{'co_yield' cannot be used in a constexpr function}}
  // expected-error@-1 {{'co_yield' cannot be used in a function with a deduced return type}}
}

void varargs_coroutine(const char *, ...) {
  co_await a; // expected-error {{'co_await' cannot be used in a varargs function}}
}

auto deduced_return_coroutine() {
  co_await a; // expected-error {{'co_await' cannot be used in a function with a deduced return type}}
}

struct outer {};
struct await_arg_1 {};
struct await_arg_2 {};

namespace adl_ns {
struct coawait_arg_type {};
awaitable operator co_await(coawait_arg_type) noexcept;
} // namespace adl_ns

namespace dependent_operator_co_await_lookup {
template <typename T> void await_template(T t) {
  // no unqualified lookup results
  co_await t; // expected-error {{no member named 'await_ready' in 'dependent_operator_co_await_lookup::not_awaitable'}}
  // expected-error@-1 {{call to function 'operator co_await' that is neither visible in the template definition nor found by argument-dependent lookup}}
};
template void await_template(awaitable);

struct indirectly_awaitable {
  indirectly_awaitable(outer);
};
awaitable operator co_await(indirectly_awaitable); // expected-note {{should be declared prior to}}
template void await_template(indirectly_awaitable);

struct not_awaitable {};
template void await_template(not_awaitable); // expected-note {{instantiation}}

template <typename T> void await_template_2(T t) {
  // one unqualified lookup result
  co_await t;
};
template void await_template(outer); // expected-note {{instantiation}}
template void await_template_2(outer);

struct transform_awaitable {};
struct transformed {};

struct transform_promise {
  typedef transform_awaitable await_arg;
  coro<transform_promise> get_return_object();
  transformed initial_suspend();
  ::adl_ns::coawait_arg_type final_suspend() noexcept;
  transformed await_transform(transform_awaitable);
  void unhandled_exception();
  void return_void();
};
template <class AwaitArg>
struct basic_promise {
  typedef AwaitArg await_arg;
  coro<basic_promise> get_return_object();
  awaitable initial_suspend();
  awaitable final_suspend() noexcept;
  void unhandled_exception();
  void return_void();
};

awaitable operator co_await(await_arg_1);

template <typename T, typename U>
coro<T> await_template_3(U t) {
  co_await t;
}

template coro<basic_promise<await_arg_1>> await_template_3<basic_promise<await_arg_1>>(await_arg_1);

template <class T, int I = 0>
struct dependent_member {
  coro<T> mem_fn() const {
    co_await typename T::await_arg{}; // expected-error {{call to function 'operator co_await'}}}
  }
  template <class U>
  coro<T> dep_mem_fn(U t) {
    co_await t;
  }
};

template <>
struct dependent_member<long> {
  // FIXME this diagnostic is terrible
  coro<transform_promise> mem_fn() const { // expected-error {{no member named 'await_ready' in 'dependent_operator_co_await_lookup::transformed'}}
    // expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
    // expected-note@+1 {{function is a coroutine due to use of 'co_await' here}}
    co_await transform_awaitable{};
    // expected-error@-1 {{no member named 'await_ready'}}
  }
  template <class R, class U>
  coro<R> dep_mem_fn(U u) { co_await u; }
};

awaitable operator co_await(await_arg_2); // expected-note {{'operator co_await' should be declared prior to the call site}}

template struct dependent_member<basic_promise<await_arg_1>, 0>;
template struct dependent_member<basic_promise<await_arg_2>, 0>; // expected-note {{in instantiation}}

template <>
coro<transform_promise>
// FIXME this diagnostic is terrible
dependent_member<long>::dep_mem_fn<transform_promise>(int) { // expected-error {{no member named 'await_ready' in 'dependent_operator_co_await_lookup::transformed'}}
  //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
  //expected-note@+1 {{function is a coroutine due to use of 'co_await' here}}
  co_await transform_awaitable{};
  // expected-error@-1 {{no member named 'await_ready'}}
}

void operator co_await(transform_awaitable) = delete;
awaitable operator co_await(transformed);

template coro<transform_promise>
    dependent_member<long>::dep_mem_fn<transform_promise>(transform_awaitable);

template <>
coro<transform_promise> dependent_member<long>::dep_mem_fn<transform_promise>(long) {
  co_await transform_awaitable{};
}

template <>
struct dependent_member<int> {
  coro<transform_promise> mem_fn() const {
    co_await transform_awaitable{};
  }
};

template coro<transform_promise> await_template_3<transform_promise>(transform_awaitable);
template struct dependent_member<transform_promise>;
template coro<transform_promise> dependent_member<transform_promise>::dep_mem_fn(transform_awaitable);
} // namespace dependent_operator_co_await_lookup

struct yield_fn_tag {};
template <>
struct std::experimental::coroutine_traits<void, yield_fn_tag> {
  struct promise_type {
    // FIXME: add an await_transform overload for functions
    awaitable yield_value(int());
    void return_value(int());

    suspend_never initial_suspend();
    suspend_never final_suspend() noexcept;
    void get_return_object();
    void unhandled_exception();
  };
};

namespace placeholder {
awaitable f(), f(int); // expected-note 4{{possible target}}
int g(), g(int);       // expected-note 2{{candidate}}
void x() {
  co_await f; // expected-error {{reference to overloaded function}}
}
void y() {
  co_yield g; // expected-error {{no matching member function for call to 'yield_value'}}
}
void z() {
  co_await a;
  co_return g; // expected-error {{address of overloaded function 'g' does not match required type 'int'}}
}

void x(yield_fn_tag) {
  co_await f; // expected-error {{reference to overloaded function}}
}
void y(yield_fn_tag) {
  co_yield g;
}
void z(yield_fn_tag) {
  co_await a;
  co_return g;
}
} // namespace placeholder

struct bad_promise_1 {
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;
  void unhandled_exception();
  void return_void();
};
coro<bad_promise_1> missing_get_return_object() { // expected-error {{no member named 'get_return_object' in 'bad_promise_1'}}
  co_await a;
}

struct bad_promise_2 {
  coro<bad_promise_2> get_return_object();
  suspend_always final_suspend() noexcept;
  void unhandled_exception();
  void return_void();
};
// FIXME: This shouldn't happen twice
coro<bad_promise_2> missing_initial_suspend() { // expected-error {{no member named 'initial_suspend' in 'bad_promise_2'}}
  co_await a;
}

struct bad_promise_3 {
  coro<bad_promise_3> get_return_object();
  suspend_always initial_suspend();
  void unhandled_exception();
  void return_void();
};
coro<bad_promise_3> missing_final_suspend() noexcept { // expected-error {{no member named 'final_suspend' in 'bad_promise_3'}}
  co_await a;
}

struct bad_promise_4 {
  coro<bad_promise_4> get_return_object();
  not_awaitable initial_suspend();
  suspend_always final_suspend() noexcept;
  void return_void();
};
// FIXME: This diagnostic is terrible.
coro<bad_promise_4> bad_initial_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
  // expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
  co_await a; // expected-note {{function is a coroutine due to use of 'co_await' here}}
}

struct bad_promise_5 {
  coro<bad_promise_5> get_return_object();
  suspend_always initial_suspend();
  not_awaitable final_suspend() noexcept;
  void return_void();
};
// FIXME: This diagnostic is terrible.
coro<bad_promise_5> bad_final_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
  // expected-note@-1 {{call to 'final_suspend' implicitly required by the final suspend point}}
  co_await a; // expected-note {{function is a coroutine due to use of 'co_await' here}}
}

struct bad_promise_6 {
  coro<bad_promise_6> get_return_object();
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;
  void unhandled_exception();
  void return_void();           // expected-note 2 {{member 'return_void' first declared here}}
  void return_value(int) const; // expected-note 2 {{member 'return_value' first declared here}}
  void return_value(int);
};
coro<bad_promise_6> bad_implicit_return() { // expected-error {{'bad_promise_6' declares both 'return_value' and 'return_void'}}
  co_await a;
}

template <class T>
coro<T> bad_implicit_return_dependent(T) { // expected-error {{'bad_promise_6' declares both 'return_value' and 'return_void'}}
  co_await a;
}
template coro<bad_promise_6> bad_implicit_return_dependent(bad_promise_6); // expected-note {{in instantiation}}

struct bad_promise_7 { // expected-note 2 {{defined here}}
  coro<bad_promise_7> get_return_object();
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;
  void return_void();
};
coro<bad_promise_7> no_unhandled_exception() { // expected-error {{'bad_promise_7' is required to declare the member 'unhandled_exception()'}}
  co_await a;
}

template <class T>
coro<T> no_unhandled_exception_dependent(T) { // expected-error {{'bad_promise_7' is required to declare the member 'unhandled_exception()'}}
  co_await a;
}
template coro<bad_promise_7> no_unhandled_exception_dependent(bad_promise_7); // expected-note {{in instantiation}}

struct bad_promise_base {
private:
  void return_void(); // expected-note 2 {{declared private here}}
};
struct bad_promise_8 : bad_promise_base {
  coro<bad_promise_8> get_return_object();
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;
  void unhandled_exception() __attribute__((unavailable)); // expected-note 2 {{marked unavailable here}}
  void unhandled_exception() const;
  void unhandled_exception(void *) const;
};
coro<bad_promise_8> calls_unhandled_exception() {
  // expected-error@-1 {{'unhandled_exception' is unavailable}}
  // expected-error@-2 {{'return_void' is a private member}}
  co_await a;
}

template <class T>
coro<T> calls_unhandled_exception_dependent(T) {
  // expected-error@-1 {{'unhandled_exception' is unavailable}}
  // expected-error@-2 {{'return_void' is a private member}}
  co_await a;
}
template coro<bad_promise_8> calls_unhandled_exception_dependent(bad_promise_8); // expected-note {{in instantiation}}

struct bad_promise_9 {
  coro<bad_promise_9> get_return_object();
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;
  void await_transform(void *);
  awaitable await_transform(int) __attribute__((unavailable)); // expected-note {{explicitly marked unavailable}}
  void return_void();
  void unhandled_exception();
};
coro<bad_promise_9> calls_await_transform() {
  co_await 42; // expected-error {{'await_transform' is unavailable}}
}

struct bad_promise_10 {
  coro<bad_promise_10> get_return_object();
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;
  int await_transform;
  void return_void();
  void unhandled_exception();
};
coro<bad_promise_10> bad_coawait() {
  // FIXME this diagnostic is terrible
  co_await 42; // expected-error {{called object type 'int' is not a function or function pointer}}
  // expected-note@-1 {{call to 'await_transform' implicitly required by 'co_await' here}}
}

struct call_operator {
  template <class... Args>
  awaitable operator()(Args...) const { return a; }
};
void ret_void();
struct good_promise_1 {
  coro<good_promise_1> get_return_object();
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;
  void unhandled_exception();
  static const call_operator await_transform;
  using Fn = void (*)();
  Fn return_void = ret_void;
};
const call_operator good_promise_1::await_transform;
coro<good_promise_1> ok_static_coawait() {
  // FIXME this diagnostic is terrible
  co_await 42;
}

template <typename T> void ok_generic_lambda_coawait_PR41909() {
  [](auto &arg) -> coro<good_promise_1> { // expected-warning {{expression result unused}}
    co_await 12;
  };
  [](auto &arg) -> coro<good_promise_1> {
    co_await 24;
  }("argument");
  [](auto &arg) -> coro<good_promise_1> { // expected-warning {{expression result unused}}
    []() -> coro<good_promise_1> {
      co_await 36;
    };
    co_await 48;
  };
}
template void ok_generic_lambda_coawait_PR41909<int>(); // expected-note {{in instantiation of function template specialization 'ok_generic_lambda_coawait_PR41909<int>' requested here}}

template <> struct std::experimental::coroutine_traits<int, int, const char **> { using promise_type = promise; };

int main(int, const char **) {
  co_await a; // expected-error {{'co_await' cannot be used in the 'main' function}}
}

struct good_promise_2 {
  float get_return_object();
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;
  void return_void();
  void unhandled_exception();
};
template <> struct std::experimental::coroutine_handle<good_promise_2> {};

template <> struct std::experimental::coroutine_traits<float> { using promise_type = good_promise_2; };

float badly_specialized_coro_handle() { // expected-error {{std::coroutine_handle must have a member named 'from_address'}}
  //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
  co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
}

namespace std {
struct nothrow_t {};
constexpr nothrow_t nothrow = {};
} // namespace std

using SizeT = decltype(sizeof(int));

void *operator new(SizeT __sz, const std::nothrow_t &) noexcept;
void operator delete(void *__p, const std::nothrow_t &)noexcept;

struct promise_on_alloc_failure_tag {};

template <>
struct std::experimental::coroutine_traits<int, promise_on_alloc_failure_tag> {
  struct promise_type {
    int get_return_object() {}
    suspend_always initial_suspend() { return {}; }
    suspend_always final_suspend() noexcept { return {}; }
    void return_void() {}
    int get_return_object_on_allocation_failure(); // expected-error{{'promise_type': 'get_return_object_on_allocation_failure()' must be a static member function}}
    void unhandled_exception();
  };
};

extern "C" int f(promise_on_alloc_failure_tag) {
  co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
}

struct bad_promise_11 {
  coro<bad_promise_11> get_return_object();
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;
  void unhandled_exception();
  void return_void();

private:
  static coro<bad_promise_11> get_return_object_on_allocation_failure(); // expected-note 2 {{declared private here}}
};
coro<bad_promise_11> private_alloc_failure_handler() {
  // expected-error@-1 {{'get_return_object_on_allocation_failure' is a private member of 'bad_promise_11'}}
  co_return; // FIXME: Add a "declared coroutine here" note.
}

template <class T>
coro<T> dependent_private_alloc_failure_handler(T) {
  // expected-error@-1 {{'get_return_object_on_allocation_failure' is a private member of 'bad_promise_11'}}
  co_return; // FIXME: Add a "declared coroutine here" note.
}
template coro<bad_promise_11> dependent_private_alloc_failure_handler(bad_promise_11);
// expected-note@-1 {{requested here}}

struct bad_promise_12 {
  coro<bad_promise_12> get_return_object();
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;
  void unhandled_exception();
  void return_void();
  static coro<bad_promise_12> get_return_object_on_allocation_failure();

  static void *operator new(SizeT);
  // expected-error@-1 2 {{'operator new' is required to have a non-throwing noexcept specification when the promise type declares 'get_return_object_on_allocation_failure()'}}
};
coro<bad_promise_12> throwing_in_class_new() { // expected-note {{call to 'operator new' implicitly required by coroutine function here}}
  co_return;
}

template <class T>
coro<T> dependent_throwing_in_class_new(T) { // expected-note {{call to 'operator new' implicitly required by coroutine function here}}
  co_return;
}
template coro<bad_promise_12> dependent_throwing_in_class_new(bad_promise_12); // expected-note {{requested here}}

struct good_promise_13 {
  coro<good_promise_13> get_return_object();
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;
  void unhandled_exception();
  void return_void();
  static coro<good_promise_13> get_return_object_on_allocation_failure();
};
coro<good_promise_13> uses_nothrow_new() {
  co_return;
}

template <class T>
coro<T> dependent_uses_nothrow_new(T) {
  co_return;
}
template coro<good_promise_13> dependent_uses_nothrow_new(good_promise_13);

struct good_promise_custom_new_operator {
  coro<good_promise_custom_new_operator> get_return_object();
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;
  void return_void();
  void unhandled_exception();
  void *operator new(SizeT, double, float, int);
};

coro<good_promise_custom_new_operator>
good_coroutine_calls_custom_new_operator(double, float, int) {
  co_return;
}

struct coroutine_nonstatic_member_struct;

struct good_promise_nonstatic_member_custom_new_operator {
  coro<good_promise_nonstatic_member_custom_new_operator> get_return_object();
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;
  void return_void();
  void unhandled_exception();
  void *operator new(SizeT, coroutine_nonstatic_member_struct &, double);
};

struct good_promise_noexcept_custom_new_operator {
  static coro<good_promise_noexcept_custom_new_operator> get_return_object_on_allocation_failure();
  coro<good_promise_noexcept_custom_new_operator> get_return_object();
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;
  void return_void();
  void unhandled_exception();
  void *operator new(SizeT, double, float, int) noexcept;
};

coro<good_promise_noexcept_custom_new_operator>
good_coroutine_calls_noexcept_custom_new_operator(double, float, int) {
  co_return;
}

struct mismatch_gro_type_tag1 {};
template <>
struct std::experimental::coroutine_traits<int, mismatch_gro_type_tag1> {
  struct promise_type {
    void get_return_object() {} //expected-note {{member 'get_return_object' declared here}}
    suspend_always initial_suspend() { return {}; }
    suspend_always final_suspend() noexcept { return {}; }
    void return_void() {}
    void unhandled_exception();
  };
};

extern "C" int f(mismatch_gro_type_tag1) {
  // expected-error@-1 {{cannot initialize return object of type 'int' with an rvalue of type 'void'}}
  co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
}

struct mismatch_gro_type_tag2 {};
template <>
struct std::experimental::coroutine_traits<int, mismatch_gro_type_tag2> {
  struct promise_type {
    void *get_return_object() {} //expected-note {{member 'get_return_object' declared here}}
    suspend_always initial_suspend() { return {}; }
    suspend_always final_suspend() noexcept { return {}; }
    void return_void() {}
    void unhandled_exception();
  };
};

extern "C" int f(mismatch_gro_type_tag2) {
  // cxx2b-error@-1 {{cannot initialize return object of type 'int' with an rvalue of type 'void *'}}
  // cxx14_20-error@-2 {{cannot initialize return object of type 'int' with an lvalue of type 'void *'}}
  co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
}

struct mismatch_gro_type_tag3 {};
template <>
struct std::experimental::coroutine_traits<int, mismatch_gro_type_tag3> {
  struct promise_type {
    int get_return_object() {}
    static void get_return_object_on_allocation_failure() {} //expected-note {{member 'get_return_object_on_allocation_failure' declared here}}
    suspend_always initial_suspend() { return {}; }
    suspend_always final_suspend() noexcept { return {}; }
    void return_void() {}
    void unhandled_exception();
  };
};

extern "C" int f(mismatch_gro_type_tag3) {
  // expected-error@-1 {{cannot initialize return object of type 'int' with an rvalue of type 'void'}}
  co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
}

struct mismatch_gro_type_tag4 {};
template <>
struct std::experimental::coroutine_traits<int, mismatch_gro_type_tag4> {
  struct promise_type {
    int get_return_object() {}
    static char *get_return_object_on_allocation_failure() {} //expected-note {{member 'get_return_object_on_allocation_failure' declared}}
    suspend_always initial_suspend() { return {}; }
    suspend_always final_suspend() noexcept { return {}; }
    void return_void() {}
    void unhandled_exception();
  };
};

extern "C" int f(mismatch_gro_type_tag4) {
  // expected-error@-1 {{cannot initialize return object of type 'int' with an rvalue of type 'char *'}}
  co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
}

struct bad_await_suspend_return {
  bool await_ready();
  // expected-error@+1 {{return type of 'await_suspend' is required to be 'void' or 'bool' (have 'char')}}
  char await_suspend(std::experimental::coroutine_handle<>);
  void await_resume();
};
struct bad_await_ready_return {
  // expected-note@+1 {{return type of 'await_ready' is required to be contextually convertible to 'bool'}}
  void await_ready();
  bool await_suspend(std::experimental::coroutine_handle<>);
  void await_resume();
};
struct await_ready_explicit_bool {
  struct BoolT {
    explicit operator bool() const;
  };
  BoolT await_ready();
  void await_suspend(std::experimental::coroutine_handle<>);
  void await_resume();
};
template <class SuspendTy>
struct await_suspend_type_test {
  bool await_ready();
  // expected-error@+2 {{return type of 'await_suspend' is required to be 'void' or 'bool' (have 'bool &')}}
  // expected-error@+1 {{return type of 'await_suspend' is required to be 'void' or 'bool' (have 'bool &&')}}
  SuspendTy await_suspend(std::experimental::coroutine_handle<>);
  // cxx20_2b-warning@-1 {{volatile-qualified return type 'const volatile bool' is deprecated}}
  void await_resume();
};
void test_bad_suspend() {
  {
    // FIXME: The actual error emitted here is terrible, and no number of notes can save it.
    bad_await_ready_return a;
    // expected-error@+1 {{value of type 'void' is not contextually convertible to 'bool'}}
    co_await a; // expected-note {{call to 'await_ready' implicitly required by coroutine function here}}
  }
  {
    bad_await_suspend_return b;
    co_await b; // expected-note {{call to 'await_suspend' implicitly required by coroutine function here}}
  }
  {
    await_ready_explicit_bool c;
    co_await c; // OK
  }
  {
    await_suspend_type_test<bool &&> a;
    await_suspend_type_test<bool &> b;
    await_suspend_type_test<const void> c;
    await_suspend_type_test<const volatile bool> d; // cxx20_2b-note {{in instantiation of template class}}
    co_await a;                                     // expected-note {{call to 'await_suspend' implicitly required by coroutine function here}}
    co_await b;                                     // expected-note {{call to 'await_suspend' implicitly required by coroutine function here}}
    co_await c;                                     // OK
    co_await d;                                     // OK
  }
}

template <int ID = 0>
struct NoCopy {
  NoCopy(NoCopy const &) = delete; // expected-note 2 {{deleted here}}
};
template <class T, class U>
void test_dependent_param(T t, U) {
  // expected-error@-1 {{call to deleted constructor of 'NoCopy<0>'}}
  // expected-error@-2 {{call to deleted constructor of 'NoCopy<1>'}}
  ((void)t);
  co_return 42;
}
template void test_dependent_param(NoCopy<0>, NoCopy<1>); // expected-note {{requested here}}

namespace CoroHandleMemberFunctionTest {
struct CoroMemberTag {};
struct BadCoroMemberTag {};

template <class T, class U>
constexpr bool IsSameV = false;
template <class T>
constexpr bool IsSameV<T, T> = true;

template <class T>
struct TypeTest {
  template <class U>
  static constexpr bool IsSame = IsSameV<T, U>;

  template <class... Args>
  static constexpr bool MatchesArgs = IsSameV<T,
                                              std::experimental::coroutine_traits<CoroMemberTag, Args...>>;
};

template <class T>
struct AwaitReturnsType {
  bool await_ready() const;
  void await_suspend(...) const;
  T await_resume() const;
};

template <class... CoroTraitsArgs>
struct CoroMemberPromise {
  using TraitsT = std::experimental::coroutine_traits<CoroTraitsArgs...>;
  using TypeTestT = TypeTest<TraitsT>;
  using AwaitTestT = AwaitReturnsType<TypeTestT>;

  CoroMemberTag get_return_object();
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;

  AwaitTestT yield_value(int);

  void return_void();
  void unhandled_exception();
};

} // namespace CoroHandleMemberFunctionTest

template <class... Args>
struct ::std::experimental::coroutine_traits<CoroHandleMemberFunctionTest::CoroMemberTag, Args...> {
  using promise_type = CoroHandleMemberFunctionTest::CoroMemberPromise<CoroHandleMemberFunctionTest::CoroMemberTag, Args...>;
};

namespace CoroHandleMemberFunctionTest {
struct TestType {

  CoroMemberTag test_qual() {
    auto TC = co_yield 0;
    static_assert(TC.MatchesArgs<TestType &>, "");
    static_assert(!TC.MatchesArgs<TestType>, "");
    static_assert(!TC.MatchesArgs<TestType *>, "");
  }

  CoroMemberTag test_asserts(int *) const {
    auto TC = co_yield 0;
    static_assert(TC.MatchesArgs<const TestType &>, ""); // expected-error {{static_assert failed}}
    static_assert(TC.MatchesArgs<const TestType &>, ""); // expected-error {{static_assert failed}}
    static_assert(TC.MatchesArgs<const TestType &, int *>, "");
  }

  CoroMemberTag test_qual(int *, const float &&, volatile void *volatile) const {
    // cxx20_2b-warning@-1 {{volatile-qualified parameter type}}
    auto TC = co_yield 0;
    static_assert(TC.MatchesArgs<const TestType &, int *, const float &&, volatile void *volatile>, "");
  }

  CoroMemberTag test_qual() const volatile {
    auto TC = co_yield 0;
    static_assert(TC.MatchesArgs<const volatile TestType &>, "");
  }

  CoroMemberTag test_ref_qual() & {
    auto TC = co_yield 0;
    static_assert(TC.MatchesArgs<TestType &>, "");
  }
  CoroMemberTag test_ref_qual() const & {
    auto TC = co_yield 0;
    static_assert(TC.MatchesArgs<TestType const &>, "");
  }
  CoroMemberTag test_ref_qual() && {
    auto TC = co_yield 0;
    static_assert(TC.MatchesArgs<TestType &&>, "");
  }
  CoroMemberTag test_ref_qual(const char *&) const volatile && {
    auto TC = co_yield 0;
    static_assert(TC.MatchesArgs<TestType const volatile &&, const char *&>, "");
  }

  CoroMemberTag test_args(int) {
    auto TC = co_yield 0;
    static_assert(TC.MatchesArgs<TestType &, int>, "");
  }
  CoroMemberTag test_args(int, long &, void *) const {
    auto TC = co_yield 0;
    static_assert(TC.MatchesArgs<TestType const &, int, long &, void *>, "");
  }

  template <class... Args>
  CoroMemberTag test_member_template(Args...) const && {
    auto TC = co_yield 0;
    static_assert(TC.template MatchesArgs<TestType const &&, Args...>, "");
  }

  static CoroMemberTag test_static() {
    auto TC = co_yield 0;
    static_assert(TC.MatchesArgs<>, "");
    static_assert(!TC.MatchesArgs<TestType>, "");
    static_assert(!TC.MatchesArgs<TestType &>, "");
    static_assert(!TC.MatchesArgs<TestType *>, "");
  }

  static CoroMemberTag test_static(volatile void *const, char &&) {
    auto TC = co_yield 0;
    static_assert(TC.MatchesArgs<volatile void *const, char &&>, "");
  }

  template <class Dummy>
  static CoroMemberTag test_static_template(const char *volatile &, unsigned) {
    auto TC = co_yield 0;
    using TCT = decltype(TC);
    static_assert(TCT::MatchesArgs<const char *volatile &, unsigned>, "");
    static_assert(!TCT::MatchesArgs<TestType &, const char *volatile &, unsigned>, "");
  }

  BadCoroMemberTag test_diagnostics() {
    // expected-error@-1 {{this function cannot be a coroutine: 'std::experimental::coroutine_traits<CoroHandleMemberFunctionTest::BadCoroMemberTag, CoroHandleMemberFunctionTest::TestType &>' has no member named 'promise_type'}}
    co_return;
  }
  BadCoroMemberTag test_diagnostics(int) const && {
    // expected-error@-1 {{this function cannot be a coroutine: 'std::experimental::coroutine_traits<CoroHandleMemberFunctionTest::BadCoroMemberTag, const CoroHandleMemberFunctionTest::TestType &&, int>' has no member named 'promise_type'}}
    co_return;
  }

  static BadCoroMemberTag test_static_diagnostics(long *) {
    // expected-error@-1 {{this function cannot be a coroutine: 'std::experimental::coroutine_traits<CoroHandleMemberFunctionTest::BadCoroMemberTag, long *>' has no member named 'promise_type'}}
    co_return;
  }
};

template CoroMemberTag TestType::test_member_template(long, const char *) const &&;
template CoroMemberTag TestType::test_static_template<void>(const char *volatile &, unsigned);

template <class... Args>
struct DepTestType {

  CoroMemberTag test_asserts(int *) const {
    auto TC = co_yield 0;
    static_assert(TC.template MatchesArgs<const DepTestType &>, ""); // expected-error {{static_assert failed}}
    static_assert(TC.template MatchesArgs<>, "");                    // expected-error {{static_assert failed}}
    static_assert(TC.template MatchesArgs<const DepTestType &, int *>, "");
  }

  CoroMemberTag test_qual() {
    auto TC = co_yield 0;
    static_assert(TC.template MatchesArgs<DepTestType &>, "");
    static_assert(!TC.template MatchesArgs<DepTestType>, "");
    static_assert(!TC.template MatchesArgs<DepTestType *>, "");
  }

  CoroMemberTag test_qual(int *, const float &&, volatile void *volatile) const {
    // cxx20_2b-warning@-1 {{volatile-qualified parameter type}}
    auto TC = co_yield 0;
    static_assert(TC.template MatchesArgs<const DepTestType &, int *, const float &&, volatile void *volatile>, "");
  }

  CoroMemberTag test_qual() const volatile {
    auto TC = co_yield 0;
    static_assert(TC.template MatchesArgs<const volatile DepTestType &>, "");
  }

  CoroMemberTag test_ref_qual() & {
    auto TC = co_yield 0;
    static_assert(TC.template MatchesArgs<DepTestType &>, "");
  }
  CoroMemberTag test_ref_qual() const & {
    auto TC = co_yield 0;
    static_assert(TC.template MatchesArgs<DepTestType const &>, "");
  }
  CoroMemberTag test_ref_qual() && {
    auto TC = co_yield 0;
    static_assert(TC.template MatchesArgs<DepTestType &&>, "");
  }
  CoroMemberTag test_ref_qual(const char *&) const volatile && {
    auto TC = co_yield 0;
    static_assert(TC.template MatchesArgs<DepTestType const volatile &&, const char *&>, "");
  }

  CoroMemberTag test_args(int) {
    auto TC = co_yield 0;
    static_assert(TC.template MatchesArgs<DepTestType &, int>, "");
  }
  CoroMemberTag test_args(int, long &, void *) const {
    auto TC = co_yield 0;
    static_assert(TC.template MatchesArgs<DepTestType const &, int, long &, void *>, "");
  }

  template <class... UArgs>
  CoroMemberTag test_member_template(UArgs...) const && {
    auto TC = co_yield 0;
    static_assert(TC.template MatchesArgs<DepTestType const &&, UArgs...>, "");
  }

  static CoroMemberTag test_static() {
    auto TC = co_yield 0;
    using TCT = decltype(TC);
    static_assert(TCT::MatchesArgs<>, "");
    static_assert(!TCT::MatchesArgs<DepTestType>, "");
    static_assert(!TCT::MatchesArgs<DepTestType &>, "");
    static_assert(!TCT::MatchesArgs<DepTestType *>, "");

    // Ensure diagnostics are actually being generated here
    static_assert(TCT::MatchesArgs<int>, ""); // expected-error {{static_assert failed}}
  }

  static CoroMemberTag test_static(volatile void *const, char &&) {
    auto TC = co_yield 0;
    using TCT = decltype(TC);
    static_assert(TCT::MatchesArgs<volatile void *const, char &&>, "");
  }

  template <class Dummy>
  static CoroMemberTag test_static_template(const char *volatile &, unsigned) {
    auto TC = co_yield 0;
    using TCT = decltype(TC);
    static_assert(TCT::MatchesArgs<const char *volatile &, unsigned>, "");
    static_assert(!TCT::MatchesArgs<DepTestType &, const char *volatile &, unsigned>, "");
  }
};

template struct DepTestType<int>; // expected-note {{requested here}}
template CoroMemberTag DepTestType<int>::test_member_template(long, const char *) const &&;

template CoroMemberTag DepTestType<int>::test_static_template<void>(const char *volatile &, unsigned);

struct bad_promise_deleted_constructor {
  // expected-note@+1 {{'bad_promise_deleted_constructor' has been explicitly marked deleted here}}
  bad_promise_deleted_constructor() = delete;
  coro<bad_promise_deleted_constructor> get_return_object();
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;
  void return_void();
  void unhandled_exception();
};

coro<bad_promise_deleted_constructor>
bad_coroutine_calls_deleted_promise_constructor() {
  // expected-error@-1 {{call to deleted constructor of 'std::experimental::coroutine_traits<coro<CoroHandleMemberFunctionTest::bad_promise_deleted_constructor>>::promise_type' (aka 'CoroHandleMemberFunctionTest::bad_promise_deleted_constructor')}}
  co_return;
}

// Test that, when the promise type has a constructor whose signature matches
// that of the coroutine function, that constructor is used. If no matching
// constructor exists, the default constructor is used as a fallback. If no
// matching constructors exist at all, an error is emitted. This is an
// experimental feature that will be proposed for the Coroutines TS.

struct good_promise_default_constructor {
  good_promise_default_constructor(double, float, int);
  good_promise_default_constructor() = default;
  coro<good_promise_default_constructor> get_return_object();
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;
  void return_void();
  void unhandled_exception();
};

coro<good_promise_default_constructor>
good_coroutine_calls_default_constructor() {
  co_return;
}

struct some_class;

struct good_promise_custom_constructor {
  good_promise_custom_constructor(some_class &, float, int);
  good_promise_custom_constructor(double, float, int);
  good_promise_custom_constructor() = delete;
  coro<good_promise_custom_constructor> get_return_object();
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;
  void return_void();
  void unhandled_exception();
};

coro<good_promise_custom_constructor>
good_coroutine_calls_custom_constructor(double, float, int) {
  co_return;
}

struct some_class {
  coro<good_promise_custom_constructor>
  good_coroutine_calls_custom_constructor(float, int) {
    co_return;
  }
  coro<good_promise_custom_constructor> static good_coroutine_calls_custom_constructor(double, float, int) {
    co_return;
  }
};

struct bad_promise_no_matching_constructor {
  bad_promise_no_matching_constructor(int, int, int);
  // expected-note@+1 2 {{'bad_promise_no_matching_constructor' has been explicitly marked deleted here}}
  bad_promise_no_matching_constructor() = delete;
  coro<bad_promise_no_matching_constructor> get_return_object();
  suspend_always initial_suspend();
  suspend_always final_suspend() noexcept;
  void return_void();
  void unhandled_exception();
};

coro<bad_promise_no_matching_constructor>
bad_coroutine_calls_with_no_matching_constructor(int, int) {
  // expected-error@-1 {{call to deleted constructor of 'std::experimental::coroutine_traits<coro<CoroHandleMemberFunctionTest::bad_promise_no_matching_constructor>, int, int>::promise_type' (aka 'CoroHandleMemberFunctionTest::bad_promise_no_matching_constructor')}}
  co_return;
}

struct some_class2 {
  coro<bad_promise_no_matching_constructor>
  bad_coroutine_calls_with_no_matching_constructor(int, int, int) {
    // expected-error@-1 {{call to deleted constructor}}
    co_return;
  }
};

} // namespace CoroHandleMemberFunctionTest

class awaitable_no_unused_warn {
public:
  using handle_type = std::experimental::coroutine_handle<>;
  constexpr bool await_ready() noexcept { return false; }
  void await_suspend(handle_type) noexcept {}
  int await_resume() noexcept { return 1; }
};

class awaitable_unused_warn {
public:
  using handle_type = std::experimental::coroutine_handle<>;
  constexpr bool await_ready() noexcept { return false; }
  void await_suspend(handle_type) noexcept {}
  [[nodiscard]] int await_resume() noexcept { return 1; }
};

template <class Await>
struct check_warning_promise {
  coro<check_warning_promise> get_return_object();
  Await initial_suspend();
  Await final_suspend() noexcept;
  Await yield_value(int);
  void return_void();
  void unhandled_exception();
};

coro<check_warning_promise<awaitable_no_unused_warn>>
test_no_unused_warning() {
  co_await awaitable_no_unused_warn();
  co_yield 42;
}

coro<check_warning_promise<awaitable_unused_warn>>
test_unused_warning() {
  co_await awaitable_unused_warn(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
  co_yield 42;                      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}

struct missing_await_ready {
  void await_suspend(std::experimental::coroutine_handle<>);
  void await_resume();
};
struct missing_await_suspend {
  bool await_ready();
  void await_resume();
};
struct missing_await_resume {
  bool await_ready();
  void await_suspend(std::experimental::coroutine_handle<>);
};

void test_missing_awaitable_members() {
  co_await missing_await_ready{};   // expected-error {{no member named 'await_ready' in 'missing_await_ready'}}
  co_await missing_await_suspend{}; // expected-error {{no member named 'await_suspend' in 'missing_await_suspend'}}
  co_await missing_await_resume{};  // expected-error {{no member named 'await_resume' in 'missing_await_resume'}}
}
