Skip to content

VS2017 fails to construct coroutine adapters for IAsyncOperation instantiations #1175

@tim-weis

Description

@tim-weis

Coroutines in a UWP/XAML application do not/no longer compile using VS2017.

Steps to reproduce the issue:

  1. Open Visual Studio 2017
  2. Create a new "Blank App (C++/WinRT)" project (call it "VS2017Compat")
  3. Replace the generated MainPage::ClickHandler with the following implementation:
    fire_and_forget MainPage::ClickHandler(IInspectable, RoutedEventArgs)
    {
        auto const selector = SmartCardReader::GetDeviceSelector();
        for (auto device : co_await DeviceInformation::FindAllAsync(selector)) {
        }
    }
    (Make sure to change the signature in the corresponding MainPage.h header to match.)
  4. Add the following include-directives and using statements:
    #include <winrt/Windows.Devices.Enumeration.h>
    #include <winrt/Windows.Devices.SmartCards.h>
    #include <winrt/Windows.UI.Core.h>
    
    using namespace Windows::Devices::Enumeration;
    using namespace Windows::Devices::SmartCards;
    using namespace Windows::UI::Xaml;
  5. Compile the code

This produces the following error diagnostic:

1>c:\...\vs2017compat\generated files\winrt\base.h(8995): error C2280: 'winrt::impl::await_adapter<winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Devices::Enumeration::DeviceInformationCollection>>::await_adapter(const winrt::impl::await_adapter<winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Devices::Enumeration::DeviceInformationCollection>> &)': attempting to reference a deleted function (compiling source file MainPage.cpp)
1>c:\...\vs2017compat\generated files\winrt\windows.foundation.h(3423): note: compiler has generated 'winrt::impl::await_adapter<winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Devices::Enumeration::DeviceInformationCollection>>::await_adapter' here (compiling source file MainPage.cpp)
1>c:\...\vs2017compat\generated files\winrt\windows.foundation.h(3423): note: 'winrt::impl::await_adapter<winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Devices::Enumeration::DeviceInformationCollection>>::await_adapter(const winrt::impl::await_adapter<winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Devices::Enumeration::DeviceInformationCollection>> &)': function was implicitly deleted because a data member invokes a deleted or inaccessible function 'std::atomic<bool>::atomic(const std::atomic<bool> &)' (compiling source file MainPage.cpp)
1>c:\...\vs2017compat\generated files\winrt\base.h(8995): note: while compiling class template member function 'winrt::impl::notify_awaiter<Expression>::notify_awaiter(T &&,winrt::cancellable_promise *)'
1>        with
1>        [
1>            Expression=winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Devices::Enumeration::DeviceInformationCollection>,
1>            T=winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Devices::Enumeration::DeviceInformationCollection>
1>        ] (compiling source file MainPage.cpp)
1>c:\...\vs2017compat\generated files\winrt\base.h(9483): note: see reference to function template instantiation 'winrt::impl::notify_awaiter<Expression>::notify_awaiter(T &&,winrt::cancellable_promise *)' being compiled
1>        with
1>        [
1>            Expression=winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Devices::Enumeration::DeviceInformationCollection>,
1>            T=winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Devices::Enumeration::DeviceInformationCollection>
1>        ] (compiling source file MainPage.cpp)
1>c:\...\vs2017compat\generated files\winrt\base.h(9482): note: see reference to class template instantiation 'winrt::impl::notify_awaiter<Expression>' being compiled
1>        with
1>        [
1>            Expression=winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Devices::Enumeration::DeviceInformationCollection>
1>        ] (compiling source file MainPage.cpp)
1>c:\...\vs2017compat\mainpage.cpp(33): note: see reference to function template instantiation 'winrt::impl::notify_awaiter<Expression> std::experimental::coroutine_traits<winrt::fire_and_forget,winrt::VS2017Compat::implementation::MainPage *,winrt::implements<D,winrt::VS2017Compat::MainPage,winrt::composing,winrt::Windows::UI::Xaml::Controls::IPageOverrides,winrt::Windows::UI::Xaml::Controls::IControlOverrides,winrt::Windows::UI::Xaml::Controls::IControlOverrides6,winrt::Windows::UI::Xaml::IFrameworkElementOverrides,winrt::Windows::UI::Xaml::IFrameworkElementOverrides2,winrt::Windows::UI::Xaml::IUIElementOverrides,winrt::Windows::UI::Xaml::IUIElementOverrides7,winrt::Windows::UI::Xaml::IUIElementOverrides8,winrt::Windows::UI::Xaml::IUIElementOverrides9,winrt::Windows::UI::Xaml::Markup::IComponentConnector,winrt::Windows::UI::Xaml::Markup::IComponentConnector2>::IInspectable,winrt::Windows::UI::Xaml::RoutedEventArgs>::promise_type::await_transform<winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Devices::Enumeration::DeviceInformationCollection>>(Expression &&)' being compiled
1>        with
1>        [
1>            Expression=winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Devices::Enumeration::DeviceInformationCollection>,
1>            D=winrt::VS2017Compat::implementation::MainPage
1>        ]
1>c:\...\vs2017compat\mainpage.cpp(33): note: see reference to class template instantiation 'winrt::impl::await_adapter<winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Devices::Enumeration::DeviceInformationCollection>>' being compiled

The code is valid (I guess), and I would have assumed that it compiled with VS2017 just fine (VS2017 is relevant to me as it is the latest version of Visual Studio that still supports deployment from layout to Windows 10 Mobile devices).

Did I forget any includes that magically enable some dismissed SFINAE branch, or has the C++/WinRT library grown beyond what VS2017 supports? If it is the latter, it would help a lot if that were changed.

Additional notes

  • The code in question compiles fine with VS2022 (I haven't verified VS2019)
  • It makes no difference whether the project is created from the template of the VS2017 C++/WinRT VSIX, or the C++/WinRT VSIX that ships with VS2022
  • The same code compiles fine in VS2017 when used in a "Windows Console Application (C++/WinRT)"
  • Possibly the same root cause as resolved in VS 2017 compatibility for enable_await_cancellation #757

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions