{"id":105539,"date":"2021-08-09T07:00:00","date_gmt":"2021-08-09T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=105539"},"modified":"2021-08-09T07:25:54","modified_gmt":"2021-08-09T14:25:54","slug":"20210809-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20210809-00\/?p=105539","title":{"rendered":"Why am I getting a weird error about <CODE>promise_<WBR>type<\/CODE> when I try to write a coroutine?"},"content":{"rendered":"<p>A customer was following <a href=\"https:\/\/kennykerr.ca\/2018\/03\/09\/cppwinrt-producing-async-objects\/\"> a tutorial by Kenny Kerr<\/a> and tried to create the world&#8217;s simplest coroutine:<\/p>\n<pre>using namespace winrt::Windows::Foundation;\r\n\r\nIAsyncAction Dummy()\r\n{\r\n    co_return;\r\n}\r\n<\/pre>\n<p>This resulted in an error:<\/p>\n<pre style=\"white-space: pre-wrap;\">\/\/ MSVC\r\nerror C2039: 'promise_<wbr \/>type': is not a member of 'std::<wbr \/>experimental::<wbr \/>coroutine_traits&lt;<wbr \/>winrt::<wbr \/>Windows::<wbr \/>Foundation::<wbr \/>IAsyncAction&gt;'\r\n\r\n\/\/ gcc\r\nerror: unable to find the promise type for this coroutine\r\n\r\n\/\/ clang\r\nthis function cannot be a coroutine: 'std::<wbr \/>experimental::<wbr \/>coroutine_traits&lt;<wbr \/>winrt::<wbr \/>Windows::<wbr \/>Foundation::<wbr \/>IAsyncAction&gt;' has no member named 'promise_<wbr \/>type'\r\n<\/pre>\n<p>What is this error trying to say?<\/p>\n<p>Recall that one of the steps in the coroutine transformation is taking the formal return type of the coroutine function, combining it with the formal parameters, and looking up a corresponding specialization of the <code>coroutine_<wbr \/>traits<\/code> type, specifically to find a nested type name <code>promise_<wbr \/>type<\/code>.<\/p>\n<p>If no such specialization exists, then the lookup for <code>promise_<wbr \/>type<\/code> fails.<\/p>\n<p>And that&#8217;s what the error message is complaining about. The error message is wearing compiler-colored glasses.<\/p>\n<p>To be fair, it&#8217;s not like the error message is intentionally being obtuse. What&#8217;s happening is that the compiler front-end performs the coroutine transformation, and then the result goes through the type resolver, and it&#8217;s the type resolver that can&#8217;t find a <code>promise_<wbr \/>type<\/code>. The type resolver doesn&#8217;t know that the request for <code>promise_<wbr \/>type<\/code> was the result of a coroutine transformation. It just reports it as a failed type lookup in the coroutine traits type.<\/p>\n<p>It looks like gcc goes the extra mile and passes some information to the type resolver that &#8220;This type is coming from a coroutine transformation&#8221;, so that it can generate a coroutine-specific error message.<\/p>\n<p>Okay, so now that we understand what the error message means, how do we fix it?<\/p>\n<p>To fix it, you need to provide the appropriate specialization of the <code>coroutine_<wbr \/>traits<\/code> type. In the case of C++\/WinRT, you get it by doing a<\/p>\n<pre>#include &lt;winrt\/Windows.Foundation.h&gt;\r\n<\/pre>\n<p>This is consistent with the overall C++\/WinRT rules that you <a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20190529-00\/?p=102527\"> must include the header file for any namespace you use<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Digging into the coroutine infrastructure for the answer.<\/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-105539","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Digging into the coroutine infrastructure for the answer.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/105539","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=105539"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/105539\/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=105539"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=105539"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=105539"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}