Issue 136700
Summary Clang on windows reject recursive variant compare
Labels clang
Assignees
Reporter neko-para
    The following code can be compiled on windows with msvc and on linux with clang, but compiling with clang on windows (both with clang-cl or clang) results error.

The code is minified from [flutter windows embedder EncodableValue](https://api.flutter.dev/windows-embedder/encodable__value_8h_source.html)

[godbolt](https://godbolt.org/#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAMzwBtMA7AQwFtMQByARg9KtQYEAysib0QXACx8BBAKoBnTAAUAHpwAMvAFYTStJg1DIApACYAQuYukl9ZATwDKjdAGFUtAK4sGIM6SuADJ4DJgAcj4ARpjEEgCcpAAOqAqETgwe3r7%2ByanpAiFhkSwxcVyJdpgOGUIETMQEWT5%2BXLaY9o4CdQ0ERRHRsXoK9Y3NOW0jvf0lZRIAlLaoXsTI7BzmAMyhyN5YANQmm24sTElH2CYaAIJbO3uYh8cAbg14hgQXV7dm2wy7XgORzcz2qRGIXxu3xGxC8Dn2ABVMCMjlYoTcvGkjIjkQQAGpvD5PAAi%2BxG6BAIFexHegmB5MpoIcJGBSJRm0uHNR32hBFh8LZBH2IH2SS8UVoeGQOJGBJpRJMAHY0dd9vsqDTXPsoqhPPtUElYkxwcCIGgGCMZZ8zAA2fa0BAKUj7c2WwXmO3ER3zQ7K75qtXETAEFYMMn1RzIAD6onZbldQsFctp1ptFwgDoUPuB4eNUpjTDjCatyY%2BHvTXqz3JuaqVxJ5ivrmxV30xoWAiJJ4YpIFO52Ogud7q5zZ5N1CQtOoQg2b9NYDCP2n1HUMbHEWtE4AFZeH4OFpSKhOG5rNYyctVo8tjxSARNOvFghMEwsHEZ6QANYgTZcAB0AA4NF%2BDR4niG0tw0f8KjMLd9E4SRd3vQ9OF4BQQA0W970WOBYBgRAUFQFgkjoWJyEoNAiJIuJnmQJIkijZ4KijAwCFxKNVBtaQaFoVjiDQiAoiQqJQgaABPTgb2E5hiFEgB5KJtDBCTeAothBFkhhaHE/deCwKIvGANwxFoNDuF0zBTiMcQdNIfAgxqUFTIPTBVGqLxWOU8hBA6JDJSiYgxI8LAkL5PAWE80FiB1JRiQswxgElIwsL4AxgAUPE8EwAB3WTDT3G9%2BEEEQxHYKQZEERQVHUGzdDaAwktMSxrH0PAojQyBFgNLoLU4AB6BlGqsSwzAPVBIppLB2vfKoamcCBXHGVpAgYdAZkGco8jSbrFr0FItoyNbSiGSYOjBWpRiaTwWmGU7ZoYHpGkOuZJgunaXumUIBiO8pFgUC81gWOCOB3Ug91Gzh9g4yR9hYBQaP2Rj4l/FjcX2CBcEIEhDl%2BLh5l4O8dPmR9n1fShFi/CCgYQ0hwspsHeCPDhUPQzDCdIHD8OWAgxQIMizUI4j6GIcJWHWVR/xtABaTj9mAZBpSkX8zF4TB8HBPAKTaQrhFEcQyu1yq1CQ2rSCygKkmUjdt0QmzGdk9yef1KhIZl2H4cR5HjVRiAPEooXsZ/PHWa0InSCfF8hnfTcOGp2mMPp5CmdsFmCZD8nv0kADOM2LcbUVDQuC3f9JEVWDo82G3waT1P13ZvCICQCjBdIih%2Bb9oZdnikauAw7jeP4wSbKksTPOHmT5MUhxPNUxgCA0rSkL0gyjNoEzPKwSyEvWA87LOxykJctyPLMrzWOjg8/ICmSgu3/GaXCk/IuizBYs3xLQDZqhUvSzKcryzztbFT1lxWQhtqoHl0AEeqxhTyWBam1eAnUkjdVMpLckRxiSDWsCNBm40NbIkQe0ToGQXArTestVan1ZjHU2gUTIV0Ji0O6k9GhM1uoPUutkJabDzofWKOtYYr0GHcIuiwn6SwVgA1xkDEGCdGaQwltLaGndsQjV/H%2BDQaMMbggDrjfGWF06bE2L%2BIxpizHmKppXBmKFk4YRrqHaOytQZIUZvowmixIppGcJIIAA%3D)

```cpp
#include <map>
#include <variant>
#include <vector>

struct Test;

using TestVariant = std::variant<std::vector<Test>>;

struct Test : public TestVariant {
  friend bool operator<(const Test& lhs, const Test& rhs) {
 return static_cast<const TestVariant&>(lhs) < static_cast<const TestVariant&>(rhs);
  }
};

using T = std::map<Test, Test>;

int main() {
    T t;
}
```

```
In file included from test.cpp:1:
In file included from C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.43.34808\include\map:11:
In file included from C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.43.34808\include\tuple:11:
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.43.34808\include\compare(347,18): error: satisfaction of constraint 'requires { { _Left < _Right } -> _Boolean_testable; { _Right < _Left } -> _Boolean_testable; }' depends on itself
  347 |         requires requires {
      | ^~~~~~~~~~
  348 |             { _Left < _Right } -> _Boolean_testable;
 |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  349 | { _Right < _Left } -> _Boolean_testable;
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  350 |         }
      | ~
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.43.34808\include\compare(347,18): note: while substituting template arguments into constraint _expression_ here
 347 |         requires requires {
      |                  ^~~~~~~~~~
 348 |             { _Left < _Right } -> _Boolean_testable;
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  349 |             { _Right < _Left } -> _Boolean_testable;
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  350 |         }
      | ~
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.43.34808\include\compare(367,42): note: while checking constraint satisfaction for template 'operator()<Test, Test>' required here
  367 | using _Synth_three_way_result = decltype(_Synth_three_way{}(_STD declval<_Ty1&>(), _STD declval<_Ty2&>()));
 |                                          ^~~~~~~~~~~~~~~~
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.43.34808\include\compare(367,42): note: while substituting deduced template arguments into function template 'operator()' [with _Ty1 = Test, _Ty2 = Test]
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.43.34808\include\vector(2316,22): note: in instantiation of template type alias '_Synth_three_way_result' requested here
 2316 | _NODISCARD constexpr _Synth_three_way_result<_Ty> operator<=>(
      |                      ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.43.34808\include\compare(321,62): note: while substituting deduced template arguments into function template 'operator<=>' [with _Ty = Test, _Alloc = std::allocator<Test>]
  321 | decltype(_STD declval<const remove_reference_t<_Ty1>&>() <=> _STD declval<const remove_reference_t<_Ty2>&>());
      | ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.43.34808\include\variant(1366,51): note: (skipping 5 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
 1366 | _NODISCARD constexpr common_comparison_category_t<compare_three_way_result_t<_Types>...> operator<=>(
      | ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.43.34808\include\compare(367,42): note: in instantiation of function template specialization 'std::_Synth_three_way::operator()<Test, Test>' requested here
  367 | using _Synth_three_way_result = decltype(_Synth_three_way{}(_STD declval<_Ty1&>(), _STD declval<_Ty2&>()));
      | ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.43.34808\include\vector(2316,22): note: in instantiation of template type alias '_Synth_three_way_result' requested here
 2316 | _NODISCARD constexpr _Synth_three_way_result<_Ty> operator<=>(
      |                      ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.43.34808\include\compare(321,62): note: while substituting deduced template arguments into function template 'operator<=>' [with _Ty = Test, _Alloc = std::allocator<Test>]
  321 | decltype(_STD declval<const remove_reference_t<_Ty1>&>() <=> _STD declval<const remove_reference_t<_Ty2>&>());
      | ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.43.34808\include\variant(1366,51): note: in instantiation of template type alias 'compare_three_way_result_t' requested here
 1366 | _NODISCARD constexpr common_comparison_category_t<compare_three_way_result_t<_Types>...> operator<=>(
      | ^
test.cpp(11,49): note: while substituting deduced template arguments into function template 'operator<=>' [with _Types = <int, std::vector<Test>>]
 11 |     return static_cast<const TestVariant&>(lhs) < static_cast<const TestVariant&>(rhs);
      | ^
In file included from test.cpp:2:
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.43.34808\include\variant(1284,20): error: no matching function for call to object of type 'std::less<void>'
 1284 |             return _Op{}(_STD _Variant_raw_get<_Idx>(_Left), _Right._Val);
      |                    ^~~~~
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.43.34808\include\variant(611,23): note: in instantiation of function template specialization 'std::_Variant_relop_visitor2<std::less<void>, bool, int, std::vector<Test>>::operator()<std::vector<Test>, 1ULL>' requested here
 611 |         _STL_STAMP(4, _STL_VISIT_STAMP);
      | ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.43.34808\include\variant(656,44): note: in instantiation of function template specialization 'std::_Variant_raw_visit1<1>::_Visit<std::_Variant_relop_visitor2<std::less<void>, bool, int, std::vector<Test>>, const
      std::_Variant_storage_<false, int, std::vector<Test>> &>' requested here
  656 |     return _Variant_raw_visit1<_Strategy>::_Visit(_Idx, static_cast<_Fn&&>(_Func), static_cast<_Storage&&>(_Obj));
      | ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.43.34808\include\variant(1321,21): note: in instantiation of function template specialization 'std::_Variant_raw_visit<const std::_Variant_storage_<false, int, std::vector<Test>> &, std::_Variant_relop_visitor2<std::less<void>, bool, int,
      std::vector<Test>>>' requested here
 1321 |             && _STD _Variant_raw_visit(_Right_offset - 1, _Right._Storage(), _Visitor{_Left._Storage()}));
      | ^
test.cpp(11,49): note: in instantiation of function template specialization 'std::operator<<int, std::vector<Test>>' requested here
   11 |     return static_cast<const TestVariant&>(lhs) < static_cast<const TestVariant&>(rhs);
      | ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.43.34808\include\type_traits(2419,31): note: candidate template ignored: substitution failure [with _Ty1 = const std::vector<Test> &, _Ty2 = const std::vector<Test> &]: invalid operands to binary _expression_
      ('const std::vector<Test>' and 'const std::vector<Test>')
 2419 |     _NODISCARD constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
      |                               ^
 2420 | noexcept(noexcept(static_cast<_Ty1&&>(_Left) < static_cast<_Ty2&&>(_Right))) // strengthened
 2421 |         -> decltype(static_cast<_Ty1&&>(_Left) < static_cast<_Ty2&&>(_Right)) {
      | ~
2 errors generated.
```

_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to