Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<expected>: std::function returning expected<any, int> emits error C7608: atomic constraint should be a constant expression #4011

Closed
StephanTLavavej opened this issue Sep 5, 2023 · 2 comments · Fixed by #4013
Labels
bug Something isn't working fixed Something works now, yay!

Comments

@StephanTLavavej
Copy link
Member

Originally reported by Jared Resch as https://godbolt.org/z/YTe7hYPrq . I've further reduced this to https://godbolt.org/z/Ebadxz43K which is accepted by libstdc++ and libc++, but rejected by VS 2022 17.8 Preview 1:

C:\Temp>type meow.cpp
#include <any>
#include <expected>
#include <functional>
using namespace std;

using X = expected<any, int>;

X meow() {
    return {};
}

int main() {
    function<X()> f{meow};
}
C:\Temp>cl /EHsc /nologo /W4 /std:c++latest meow.cpp
meow.cpp
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.32919\include\expected(258): error C7608: atomic constraint should be a constant expression
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.32919\include\expected(258): note: the template instantiation context (the oldest one first) is
meow.cpp(13): note: while processing the default template argument of 'std::function<X (void)>::function(_Fx &&)'
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.32919\include\functional(1050): note: see reference to alias template instantiation 'std::_Func_class<_Ret>::_Enable_if_callable_t<X(__cdecl &)(void),std::function<X (void)>>' being compiled
        with
        [
            _Ret=X
        ]
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.32919\include\functional(892): note: see reference to variable template 'const bool conjunction_v<std::negation<std::is_same<std::expected<std::any,int> __cdecl(void),std::function<std::expected<std::any,int> __cdecl(void)> > >,std::_Is_invocable_r<std::expected<std::any,int>,std::expected<std::any,int> (__cdecl*&)(void)> >' being compiled
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.32919\include\functional(892): note: see reference to class template instantiation 'std::_Is_invocable_r<_Ret,X (__cdecl *&)(void)>' being compiled
        with
        [
            _Ret=X
        ]
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.32919\include\type_traits(1889): note: see reference to alias template instantiation 'std::_Is_invocable_r_<_Rx,_Callable,>' being compiled
        with
        [
            _Rx=X,
            _Callable=X (__cdecl *&)(void)
        ]
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.32919\include\type_traits(1886): note: see reference to alias template instantiation 'std::_Invoke_traits_common<std::expected<std::any,int>,false>::_Is_invocable_r<_Rx>' being compiled
        with
        [
            _Rx=X
        ]
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.32919\include\type_traits(1810): note: see reference to variable template 'const bool disjunction_v<std::is_void<std::expected<std::any,int> >,std::_Invoke_convertible<std::expected<std::any,int>,std::expected<std::any,int>,void> >' being compiled
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.32919\include\expected(271): note: see reference to variable template 'const bool std::expected<std::any,int>::_Allow_unwrapping<std::any,int>' being compiled
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.32919\include\expected(242): note: see reference to variable template 'const bool disjunction_v<std::is_same<std::any,bool>,std::negation<std::disjunction<std::is_constructible<std::any,std::expected<std::any,int> &>,std::is_constructible<std::any,std::expected<std::any,int> >,std::is_constructible<std::any,std::expected<std::any,int> const &>,std::is_constructible<std::any,std::expected<std::any,int> const >,std::is_convertible<std::expected<std::any,int> &,std::any>,std::is_convertible<std::expected<std::any,int> &&,std::any>,std::is_convertible<std::expected<std::any,int> const &,std::any>,std::is_convertible<std::expected<std::any,int> const &&,std::any> > > >' being compiled
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.32919\include\expected(250): note: see reference to class template instantiation 'std::is_constructible<_Ty,std::expected<_Ty,int> &>' being compiled
        with
        [
            _Ty=std::any
        ]
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.32919\include\type_traits(755): note: while processing the default template argument of 'std::any::any(_ValueType &&)'
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.32919\include\any(138): note: see reference to variable template 'const bool conjunction_v<std::negation<std::is_same<std::expected<std::any,int>,std::any> >,std::negation<std::_Is_specialization<std::expected<std::any,int>,std::in_place_type_t> >,std::is_copy_constructible<std::expected<std::any,int> > >' being compiled
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.32919\include\expected(258): error C2131: expression did not evaluate to a constant
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.32919\include\expected(258): note: failure was caused by a read of an uninitialized symbol
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.32919\include\expected(258): note: see usage of 'std::expected<std::any,int>::_Allow_unwrapping<std::any,int>'

I haven't figured out the root cause yet (library bug? compiler bug? an LWG issue resolution we've implemented that the others haven't?).

@StephanTLavavej StephanTLavavej added the bug Something isn't working label Sep 5, 2023
@CaseyCarter
Copy link
Member

CaseyCarter commented Sep 5, 2023

My constraint recursion sense is tingling: I suspect expected<any, int> is (copy or move) constructible only if it's (copy or move) constructible. The any(T&&) constructor is a factory for constraint recursion.

EDIT: clang-cl accepts the program whereas MSVC rejects it.

EDIT 2: MSVC accepts with:

+    template <class _ValueType>
+        requires (!same_as<decay_t<_ValueType>, any> && !_Is_specialization<decay_t<_ValueType>, in_place_type_t>)
+              && copy_constructible<decay_t<_ValueType>>
-    template <class _ValueType, enable_if_t<conjunction_v<negation<is_same<decay_t<_ValueType>, any>>,
-                                                negation<_Is_specialization<decay_t<_ValueType>, in_place_type_t>>,
-                                                is_copy_constructible<decay_t<_ValueType>>>,
-                                    int> = 0>
     any(_ValueType&& _Value) { // initialize with _Value
         _Emplace<decay_t<_ValueType>>(_STD forward<_ValueType>(_Value));
     }

Maybe an MSVC bug? Nevermind, correcting _Is_specialization to _Is_specialization_v in the requires-clause produces the same error.

@achabense
Copy link
Contributor

achabense commented Sep 6, 2023

The test case will compile if expected(expected<_Uty, _UErr>&&/const&) reject expected<_Ty,_Err> (itself):

STL/stl/inc/expected

Lines 269 to 270 in 6c69a73

template <class _Uty, class _UErr>
requires is_constructible_v<_Ty, _Uty> && is_constructible_v<_Err, _UErr> && _Allow_unwrapping<_Uty, _UErr>

template <class _Uty, class _UErr>
    requires (!is_same_v<_Ty, _Uty> || !is_same_v<_Err, _UErr>) && other constraints)
...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working fixed Something works now, yay!
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants