Index: lib/Sema/SemaCoroutine.cpp =================================================================== --- lib/Sema/SemaCoroutine.cpp +++ lib/Sema/SemaCoroutine.cpp @@ -360,6 +360,15 @@ if (Result.isInvalid()) return ExprError(); + // We meant exactly what we asked for. No need for typo correction. + if (auto *TE = dyn_cast(Result.get())) { + S.clearDelayedTypo(TE); + S.Diag(Loc, diag::err_no_member) + << NameInfo.getName() << Base->getType()->getAsCXXRecordDecl() + << Base->getSourceRange(); + return ExprError(); + } + return S.ActOnCallExpr(nullptr, Result.get(), Loc, Args, Loc, nullptr); } Index: test/SemaCXX/coroutines.cpp =================================================================== --- test/SemaCXX/coroutines.cpp +++ test/SemaCXX/coroutines.cpp @@ -500,8 +500,7 @@ struct bad_promise_2 { coro get_return_object(); - // FIXME: We shouldn't offer a typo-correction here! - suspend_always final_suspend(); // expected-note {{here}} + suspend_always final_suspend(); void unhandled_exception(); void return_void(); }; @@ -512,8 +511,7 @@ struct bad_promise_3 { coro get_return_object(); - // FIXME: We shouldn't offer a typo-correction here! - suspend_always initial_suspend(); // expected-note {{here}} + suspend_always initial_suspend(); void unhandled_exception(); void return_void(); }; @@ -1162,3 +1160,22 @@ template CoroMemberTag DepTestType::test_static_template(const char *volatile &, unsigned); } // namespace CoroHandleMemberFunctionTest + +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'}} +}