{"id":103219,"date":"2019-12-17T07:00:00","date_gmt":"2019-12-17T15:00:00","guid":{"rendered":"http:\/\/devblogs.microsoft.com\/oldnewthing\/?p=103219"},"modified":"2019-12-16T18:42:57","modified_gmt":"2019-12-17T02:42:57","slug":"20191217-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20191217-00\/?p=103219","title":{"rendered":"C++ coroutines: no callable &#8216;await_resume&#8217; function found for type"},"content":{"rendered":"<p>You try to <code>co_await<\/code> something and get the error message<\/p>\n<blockquote class=\"q\"><p>no callable &#8216;await_resume&#8217; (or &#8216;await_ready&#8217; or &#8216;await_suspend&#8217;) function found for type &#8216;Expression&#8217;<\/p><\/blockquote>\n<p>What does this mean?<\/p>\n<p>Recall how the compiler generates code for <code>co_await<\/code>:<\/p>\n<table class=\"cp3\" style=\"border-collapse: collapse;\" border=\"0\" cellspacing=\"0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<td>&nbsp;<\/td>\n<td>\n<div>calculate <code>x<\/code><\/div>\n<div>obtain <code>awaiter<\/code><\/div>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"border: solid 1px black;\" rowspan=\"2\" valign=\"middle\"><code>co_await<\/code><\/td>\n<td style=\"border: solid 1px black;\">\n<div><code>if (!awaiter.await_ready())<\/code><\/div>\n<div><code>{<\/code><\/div>\n<div style=\"padding-left: 1em;\">save state for resumption<\/div>\n<div style=\"padding-left: 1em;\"><code>if (awaiter.await_suspend(handle))<\/code><\/div>\n<div style=\"padding-left: 1em;\"><code>{<\/code><\/div>\n<div style=\"padding-left: 2em;\">return to caller<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"border: solid 1px black;\">\n<div style=\"padding-left: 2em;\">[Invoking the handle resumes execution here]<\/div>\n<div style=\"padding-left: 1em;\"><code>}<\/code><\/div>\n<div style=\"padding-left: 1em;\">restore state after resumption<\/div>\n<div><code>}<\/code><\/div>\n<div><code>result = awaiter.await_resume();<\/code><\/div>\n<\/td>\n<\/tr>\n<tr>\n<td>&nbsp;<\/td>\n<td>execution continues<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The &#8220;obtain awaiter&#8221; step always succeeds because of rule 3:<\/p>\n<ol>\n<li>(We&#8217;re not ready to talk about step 1 yet.)<\/li>\n<li>(We&#8217;re not ready to talk about step 2 yet.)<\/li>\n<li>Otherwise, <code>x<\/code> is its own awaiter.<\/li>\n<\/ol>\n<p>Even if the mysterious first two steps fail, the third always succeeds.<\/p>\n<p>The other parts of the code generation require that the awaiter implement methods named <code>await_<\/code><code>ready<\/code>, <code>await_<\/code><code>suspend<\/code>, and <code>await_<\/code><code>resume<\/code>. If any of them is missing, the compiler will generate a corresponding message.<\/p>\n<p>And if <i>all of them<\/i> are missing, then the one the compiler complains about first is unpredictable. The current implementation of the compiler looks for <code>await_<\/code><code>resume<\/code> first, but that is not contractual, and future versions may look for one of the other two methods first.<\/p>\n<p>One of the reasons you may get this error is that you are awaiting something that simply isn&#8217;t awaitable.<\/p>\n<pre>struct something { };\r\n\r\nco_await something();\r\n<\/pre>\n<p>The <code>something<\/code> structure doesn&#8217;t have any of the required methods for being an awaitable object, so you will get an error.<\/p>\n<p>Another reason you may get this error is that you were expecting one of the first two steps (which we haven&#8217;t talked about yet) to produce an awaiter, but they failed. We&#8217;ll investigate this after we learn about the mysterious step 2.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The thing you want isn&#8217;t there.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-103219","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>The thing you want isn&#8217;t there.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/103219","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=103219"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/103219\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=103219"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=103219"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=103219"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}