Skip to content

MSVC compilation fails in header mode due to requires evaluation bug in get_completion_signatures_for_helper #227

Description

@ecoezen

when building the package on msvc with module disabled, compilation fails during tests (e.g. exec-associate.test.cpp) with constrain satisfaction error for sender_in/completion_signatures_of_t. when modules enabled, code compiles flawlessly.

Build Logs (Short)

󰍲 ecoezen in  …\execution on  main +0 -0
╰─❯ cmake --preset msvc-debug -DBEMAN_USE_MODULES=OFF -DBEMAN_USE_STD_MODULE=OFF
-- The CXX compiler identification is MSVC 19.50.35724.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/18/Community/VC/Tools/MSVC/14.50.35717/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES=
-- BEMAN_USE_MODULES=OFF
-- BEMAN_USE_STD_MODULE=OFF
-- CMAKE_CXX_SCAN_FOR_MODULES=OFF
CMake Warning at cmake/beman-install-library.cmake:159 (message):
beman_install_library(beman.execution): 'beman.execution' is not a target
Call Stack (most recent call first):
CMakeLists.txt:112 (beman_install_library)

-- Configuring done (1.4s)
-- Generating done (0.5s)
-- Build files have been written to: C:/Users/ecoezen/Repositories/execution/build/msvc-debug

󰍲 ecoezen in  …\execution on  main +0 -0
╰─❯ cmake --build --preset msvc-debug
[12/224] Building CXX object tests\beman\execution\CMakeFi...ecution.exec-associate.test.dir\exec-associate.test.cpp.ob
FAILED: [code=2] tests/beman/execution/CMakeFiles/beman.execution.exec-associate.test.dir/exec-associate.test.cpp.obj
C:\PROGRA1\MICROS1\18\COMMUN1\VC\Tools\MSVC\14501.357\bin\Hostx64\x64\cl.exe /nologo /TP -IC:\Users\ecoezen\Repositories\execution\tests\beman\execution\include -IC:\Users\ecoezen\Repositories\execution\include /DWIN32 /D_WINDOWS /EHsc /EHsc /permissive- /fsanitize=address /Zi /Zi /Ob0 /Od /RTC1 -std:c++latest -MDd /showIncludes /Fotests\beman\execution\CMakeFiles\beman.execution.exec-associate.test.dir\exec-associate.test.cpp.obj /Fdtests\beman\execution\CMakeFiles\beman.execution.exec-associate.test.dir\ /FS -c C:\Users\ecoezen\Repositories\execution\tests\beman\execution\exec-associate.test.cpp
C:\Users\ecoezen\Repositories\execution\tests\beman\execution\exec-associate.test.cpp(120): error C7602: 'beman::execution::completion_signatures_of_t': the associated constraints are not satisfied
C:\Users\ecoezen\Repositories\execution\include\beman/execution/detail/completion_signatures_of_t.hpp(30): note: see declaration of 'beman::execution::completion_signatures_of_t'
C:\Users\ecoezen\Repositories\execution\include\beman/execution/detail/completion_signatures_of_t.hpp(28): note: the concept 'beman::execution::sender_in<main::snd0_t,beman::execution::env<>>' evaluated to false
C:\Users\ecoezen\Repositories\execution\include\beman/execution/detail/sender_in.hpp(36): note: the concept 'beman::execution::detail::valid_completion_signaturesbeman::execution::detail::no_completion_signatures_defined_in_sender' evaluated to false
C:\Users\ecoezen\Repositories\execution\include\beman/execution/detail/valid_completion_signatures.hpp(28): note: the constraint was not satisfied
C:\Users\ecoezen\Repositories\execution\include\beman/execution/detail/sender_in.hpp(35): note: the expression was resolved to a call to 'beman::execution::get_completion_signatures_t::operator ()'
C:\Users\ecoezen\Repositories\execution\include\beman/execution/detail/get_completion_signatures.hpp(75): note: see declaration of 'beman::execution::get_completion_signatures_t::operator ()'
C:\Users\ecoezen\Repositories\execution\tests\beman\execution\exec-associate.test.cpp(119): error C2882: 'std': illegal use of namespace identifier in expression
[35/224] Building CXX object tests\beman\execution\CMakeFi...ecution.exec-affine-on.test.dir\exec-affine-on.test.cpp.ob
ninja: build stopped: subcommand failed.

it seems the failure stems from msvc bug regarding requires expressions containing dependent types.

Fix:

changing completion_signatures_for.hpp from

template <typename Sender, typename... Env>
constexpr auto get_completion_signatures_for_helper() {
    using tag_t = ::std::remove_cvref_t<::beman::execution::tag_of_t<::std::remove_cvref_t<Sender>>>;
    // MSVC BUG?: incorrectly evaluates`requires` constraints containing dependent types as FALSE,
   // when they are evaluated *inside a function template body*.
    if constexpr (requires { tag_t::template get_completion_signatures<Sender, Env...>(); })
        return tag_t::template get_completion_signatures<Sender, Env...>();
    else
        return ::beman::execution::detail::no_completion_signatures_defined_in_sender{};
}

template <typename Sender, typename... Env>
using completion_signatures_for = decltype(get_completion_signatures_for_helper<Sender, Env...>());

to the classical SFINAE partial template specialization:

template <typename Tag, typename Sender, typename... Env>
struct get_completion_signatures_for_impl {
    using type = ::beman::execution::detail::no_completion_signatures_defined_in_sender;
};

template <typename Tag, typename Sender, typename... Env>
    requires requires { Tag::template get_completion_signatures<Sender, Env...>(); }
struct get_completion_signatures_for_impl<Tag, Sender, Env...> {
    using type = decltype(Tag::template get_completion_signatures<Sender, Env...>());
};

template <typename Sender, typename... Env>
using completion_signatures_for = typename get_completion_signatures_for_impl<
    ::std::remove_cvref_t<::beman::execution::tag_of_t<::std::remove_cvref_t<Sender>>>,
    Sender,
    Env...>::type;

since it seems we're not currently testing header builds explicitly for any supported toolchains in CI, a PR for this fix won't be covered by automated testing or have any meaningful observability moving forward. should we add a dedicated CI matrix for header builds, or we should consider header builds as 'best effort' so i'd send a blind PR that i tested locally?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

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