Skip to content

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

@ecoezen

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?

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